summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-05-22 16:05:52 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-05-22 16:05:52 -0400
commita61ca06b495ea29e2cd3388b4a04114bd66b7045 (patch)
treea98fd196f93a969503de683ba5583ec42fed2a9f
parent9fb9824c1753c7aa560f755d013008cedd454388 (diff)
xwm: Add window resize support
-rw-r--r--src/compositor.h8
-rw-r--r--src/shell.c46
-rw-r--r--src/xwayland/window-manager.c63
3 files changed, 102 insertions, 15 deletions
diff --git a/src/compositor.h b/src/compositor.h
index 744b6b7b..a3ccc36c 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -55,11 +55,17 @@ struct weston_mode {
struct wl_list link;
};
+struct weston_shell_client {
+ void (*send_configure)(struct weston_surface *surface,
+ uint32_t edges, int32_t width, int32_t height);
+};
+
struct weston_shell_interface {
void *shell; /* either desktop or tablet */
struct shell_surface *(*create_shell_surface)(void *shell,
- struct weston_surface *surface);
+ struct weston_surface *surface,
+ const struct weston_shell_client *client);
void (*set_toplevel)(struct shell_surface *shsurf);
diff --git a/src/shell.c b/src/shell.c
index f8110d14..d764a792 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -160,6 +160,8 @@ struct shell_surface {
struct weston_output *fullscreen_output;
struct weston_output *output;
struct wl_list link;
+
+ const struct weston_shell_client *client;
};
struct shell_grab {
@@ -557,17 +559,18 @@ resize_grab_motion(struct wl_pointer_grab *grab,
{
struct weston_resize_grab *resize = (struct weston_resize_grab *) grab;
struct wl_pointer *pointer = grab->pointer;
+ struct shell_surface *shsurf = resize->base.shsurf;
int32_t width, height;
wl_fixed_t from_x, from_y;
wl_fixed_t to_x, to_y;
- if (!resize->base.shsurf)
+ if (!shsurf)
return;
- weston_surface_from_global_fixed(resize->base.shsurf->surface,
+ weston_surface_from_global_fixed(shsurf->surface,
pointer->grab_x, pointer->grab_y,
&from_x, &from_y);
- weston_surface_from_global_fixed(resize->base.shsurf->surface,
+ weston_surface_from_global_fixed(shsurf->surface,
pointer->x, pointer->y, &to_x, &to_y);
width = resize->width;
@@ -584,11 +587,25 @@ resize_grab_motion(struct wl_pointer_grab *grab,
height += wl_fixed_to_int(to_y - from_y);
}
- wl_shell_surface_send_configure(&resize->base.shsurf->resource,
- resize->edges, width, height);
+ shsurf->client->send_configure(shsurf->surface,
+ resize->edges, width, height);
}
static void
+send_configure(struct weston_surface *surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ struct shell_surface *shsurf = get_shell_surface(surface);
+
+ wl_shell_surface_send_configure(&shsurf->resource,
+ edges, width, height);
+}
+
+static const struct weston_shell_client shell_client = {
+ send_configure
+};
+
+static void
resize_grab_button(struct wl_pointer_grab *grab,
uint32_t time, uint32_t button, uint32_t state)
{
@@ -893,9 +910,9 @@ shell_surface_set_maximized(struct wl_client *client,
panel_height = get_output_panel_height(shell, es->output);
edges = WL_SHELL_SURFACE_RESIZE_TOP|WL_SHELL_SURFACE_RESIZE_LEFT;
- wl_shell_surface_send_configure(&shsurf->resource, edges,
- es->output->current->width,
- es->output->current->height - panel_height);
+ shsurf->client->send_configure(shsurf->surface, edges,
+ es->output->current->width,
+ es->output->current->height - panel_height);
shsurf->next_type = SHELL_SURFACE_MAXIMIZED;
}
@@ -1039,9 +1056,9 @@ shell_surface_set_fullscreen(struct wl_client *client,
shsurf->fullscreen.framerate = framerate;
shsurf->next_type = SHELL_SURFACE_FULLSCREEN;
- wl_shell_surface_send_configure(&shsurf->resource, 0,
- shsurf->output->current->width,
- shsurf->output->current->height);
+ shsurf->client->send_configure(shsurf->surface, 0,
+ shsurf->output->current->width,
+ shsurf->output->current->height);
}
static void
@@ -1247,7 +1264,8 @@ static void
shell_surface_configure(struct weston_surface *, int32_t, int32_t);
static struct shell_surface *
-create_shell_surface(void *shell, struct weston_surface *surface)
+create_shell_surface(void *shell, struct weston_surface *surface,
+ const struct weston_shell_client *client)
{
struct shell_surface *shsurf;
@@ -1294,6 +1312,8 @@ create_shell_surface(void *shell, struct weston_surface *surface)
shsurf->type = SHELL_SURFACE_NONE;
shsurf->next_type = SHELL_SURFACE_NONE;
+ shsurf->client = client;
+
return shsurf;
}
@@ -1314,7 +1334,7 @@ shell_get_shell_surface(struct wl_client *client,
return;
}
- shsurf = create_shell_surface(shell, surface);
+ shsurf = create_shell_surface(shell, surface, &shell_client);
if (!shsurf) {
wl_resource_post_error(surface_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
index 028b3b75..36270d14 100644
--- a/src/xwayland/window-manager.c
+++ b/src/xwayland/window-manager.c
@@ -99,6 +99,7 @@ struct weston_wm_window {
struct shell_surface *shsurf;
struct wl_listener surface_destroy_listener;
struct wl_event_source *repaint_source;
+ struct wl_event_source *configure_source;
int properties_dirty;
char *class;
char *name;
@@ -1156,6 +1157,65 @@ get_wm_window(struct weston_surface *surface)
}
static void
+weston_wm_window_configure(void *data)
+{
+ struct weston_wm_window *window = data;
+ struct weston_wm *wm = window->wm;
+ uint32_t values[2];
+ int width, height;
+
+ values[0] = window->width;
+ values[1] = window->height;
+ xcb_configure_window(wm->conn,
+ window->id,
+ XCB_CONFIG_WINDOW_WIDTH |
+ XCB_CONFIG_WINDOW_HEIGHT,
+ values);
+
+ weston_wm_window_get_frame_size(window, &width, &height);
+ values[0] = width;
+ values[1] = height;
+ xcb_configure_window(wm->conn,
+ window->frame_id,
+ XCB_CONFIG_WINDOW_WIDTH |
+ XCB_CONFIG_WINDOW_HEIGHT,
+ values);
+
+ window->configure_source = NULL;
+
+ weston_wm_window_schedule_repaint(window);
+}
+
+static void
+send_configure(struct weston_surface *surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ struct weston_wm_window *window = get_wm_window(surface);
+ struct weston_wm *wm = window->wm;
+ struct theme *t = window->wm->theme;
+
+ if (window->decorate) {
+ window->width = width - 2 * (t->margin + t->width);
+ window->height = height - 2 * t->margin -
+ t->titlebar_height - t->width;
+ } else {
+ window->width = width - 2 * t->margin;
+ window->height = height - 2 * t->margin;
+ }
+
+ if (window->configure_source)
+ return;
+
+ window->configure_source =
+ wl_event_loop_add_idle(wm->server->loop,
+ weston_wm_window_configure, window);
+}
+
+static const struct weston_shell_client shell_client = {
+ send_configure
+};
+
+static void
xserver_map_shell_surface(struct weston_wm *wm,
struct weston_wm_window *window)
{
@@ -1169,7 +1229,8 @@ xserver_map_shell_surface(struct weston_wm *wm,
window->shsurf =
shell_interface->create_shell_surface(shell_interface->shell,
- window->surface);
+ window->surface,
+ &shell_client);
if (!window->transient_for) {
shell_interface->set_toplevel(window->shsurf);