From a40d38798c6fabf14a690fde7ab2367455da65c6 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Oct 2017 19:14:36 +0200 Subject: [PATCH 01/20] rootston: force move and resize --- rootston/cursor.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/rootston/cursor.c b/rootston/cursor.c index c24e6989..ef941730 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,3 +1,4 @@ +#include #include #include // TODO: BSD et al @@ -141,6 +142,18 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { event->orientation, event->delta); } +static bool is_logo_pressed(struct roots_input *input) { + struct roots_keyboard *keyboard; + wl_list_for_each(keyboard, &input->keyboards, link) { + uint32_t modifiers = + wlr_keyboard_get_modifiers(keyboard->device->keyboard); + if ((modifiers ^ WLR_MODIFIER_LOGO) == 0) { + return true; + } + } + return false; +} + static void do_cursor_button_press(struct roots_input *input, struct wlr_cursor *cursor, struct wlr_input_device *device, uint32_t time, uint32_t button, uint32_t state) { @@ -148,9 +161,27 @@ static void do_cursor_button_press(struct roots_input *input, struct wlr_surface *surface; double sx, sy; struct roots_view *view = view_at(desktop, - input->cursor->x, input->cursor->y, &surface, &sx, &sy); - uint32_t serial = wlr_seat_pointer_send_button( - input->wl_seat, time, button, state); + input->cursor->x, input->cursor->y, &surface, &sx, &sy); + + if (state == WLR_BUTTON_PRESSED && view && is_logo_pressed(input)) { + set_view_focus(input, desktop, view); + + switch (button) { + case BTN_LEFT: + view_begin_move(input, cursor, view); + break; + case BTN_RIGHT: + view_begin_resize(input, cursor, view, + ROOTS_CURSOR_RESIZE_EDGE_RIGHT | + ROOTS_CURSOR_RESIZE_EDGE_BOTTOM); + break; + } + return; + } + + uint32_t serial = wlr_seat_pointer_send_button(input->wl_seat, time, button, + state); + int i; switch (state) { case WLR_BUTTON_RELEASED: From 9b88f2520862f8707e5e7b91ac0871adbe2edac9 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Oct 2017 21:06:32 +0200 Subject: [PATCH 02/20] rootston: rotate views! --- include/rootston/input.h | 1 + rootston/cursor.c | 44 ++++++++++++++++++++++++++++++++-------- rootston/output.c | 21 ++++++++++++++----- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/include/rootston/input.h b/include/rootston/input.h index 6161eb7a..21120ad2 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -83,6 +83,7 @@ struct roots_input { struct roots_view *active_view; int offs_x, offs_y; int view_x, view_y, view_width, view_height; + float view_rotation; uint32_t resize_edges; // Ring buffer of input events that could trigger move/resize/rotate diff --git a/rootston/cursor.c b/rootston/cursor.c index ef941730..00218064 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,6 +1,7 @@ #include #include #include +#include // TODO: BSD et al #include #include @@ -25,15 +26,16 @@ const struct roots_input_event *get_input_event(struct roots_input *input, void view_begin_move(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view) { input->mode = ROOTS_CURSOR_MOVE; - input->offs_x = cursor->x - view->x; - input->offs_y = cursor->y - view->y; + input->offs_x = cursor->x; + input->offs_y = cursor->y; + input->view_x = view->x; + input->view_y = view->y; wlr_seat_pointer_clear_focus(input->wl_seat); } void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, struct roots_view *view, uint32_t edges) { input->mode = ROOTS_CURSOR_RESIZE; - wlr_log(L_DEBUG, "begin resize"); input->offs_x = cursor->x; input->offs_y = cursor->y; input->view_x = view->x; @@ -46,6 +48,15 @@ void view_begin_resize(struct roots_input *input, struct wlr_cursor *cursor, wlr_seat_pointer_clear_focus(input->wl_seat); } +void view_begin_rotate(struct roots_input *input, struct wlr_cursor *cursor, + struct roots_view *view) { + input->mode = ROOTS_CURSOR_ROTATE; + input->offs_x = cursor->x; + input->offs_y = cursor->y; + input->view_rotation = view->rotation; + wlr_seat_pointer_clear_focus(input->wl_seat); +} + void cursor_update_position(struct roots_input *input, uint32_t time) { struct roots_desktop *desktop = input->server->desktop; struct roots_view *view; @@ -64,16 +75,18 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { break; case ROOTS_CURSOR_MOVE: if (input->active_view) { - input->active_view->x = input->cursor->x - input->offs_x; - input->active_view->y = input->cursor->y - input->offs_y; + int dx = input->cursor->x - input->offs_x, + dy = input->cursor->y - input->offs_y; + input->active_view->x = input->view_x + dx; + input->active_view->y = input->view_y + dy; } break; case ROOTS_CURSOR_RESIZE: if (input->active_view) { - int dx = input->cursor->x - input->offs_x; - int dy = input->cursor->y - input->offs_y; - int width = input->view_width; - int height = input->view_height; + int dx = input->cursor->x - input->offs_x, + dy = input->cursor->y - input->offs_y; + int width = input->view_width, + height = input->view_height; if (input->resize_edges & ROOTS_CURSOR_RESIZE_EDGE_TOP) { input->active_view->y = input->view_y + dy; height -= dy; @@ -92,6 +105,17 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { } break; case ROOTS_CURSOR_ROTATE: + if (input->active_view) { + struct roots_view *view = input->active_view; + int ox = view->x + view->wlr_surface->current->width/2, + oy = view->y + view->wlr_surface->current->height/2; + int ux = input->offs_x - ox, + uy = input->offs_y - oy; + int vx = input->cursor->x - ox, + vy = input->cursor->y - oy; + float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + view->rotation = input->view_rotation + angle; + } break; } } @@ -175,6 +199,8 @@ static void do_cursor_button_press(struct roots_input *input, ROOTS_CURSOR_RESIZE_EDGE_RIGHT | ROOTS_CURSOR_RESIZE_EDGE_BOTTOM); break; + case BTN_MIDDLE: + view_begin_rotate(input, cursor, view); } return; } diff --git a/rootston/output.c b/rootston/output.c index 14d1783e..b3cbaf10 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -18,7 +18,7 @@ static inline int64_t timespec_to_msec(const struct timespec *a) { static void render_surface(struct wlr_surface *surface, struct roots_desktop *desktop, struct wlr_output *wlr_output, - struct timespec *when, double lx, double ly) { + struct timespec *when, double lx, double ly, float rotation) { wlr_surface_flush_damage(surface); if (surface->texture->valid) { int width = surface->current->buffer_width; @@ -27,10 +27,20 @@ static void render_surface(struct wlr_surface *surface, wlr_output_layout_output_coords(desktop->layout, wlr_output, &ox, &oy); if (wlr_output_layout_intersects(desktop->layout, wlr_output, - lx, ly, lx + width, ly + height)) { + lx, ly, lx + width, ly + height)) { float matrix[16]; + + float translate_origin[16]; + wlr_matrix_translate(&translate_origin, + ox + width/2, oy + height/2, 0); + float rotate[16]; + wlr_matrix_rotate(&rotate, rotation); + float translate_center[16]; + wlr_matrix_translate(&translate_center, -width/2, -height/2, 0); float transform[16]; - wlr_matrix_translate(&transform, ox, oy, 0); + wlr_matrix_mul(&translate_origin, &rotate, &transform); + wlr_matrix_mul(&transform, &translate_center, &transform); + wlr_surface_get_matrix(surface, &matrix, &wlr_output->transform_matrix, &transform); wlr_render_with_matrix(desktop->server->renderer, @@ -48,7 +58,8 @@ static void render_surface(struct wlr_surface *surface, wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { render_surface(subsurface->surface, desktop, wlr_output, when, lx + subsurface->surface->current->subsurface_position.x, - ly + subsurface->surface->current->subsurface_position.y); + ly + subsurface->surface->current->subsurface_position.y, + rotation); } } } @@ -56,7 +67,7 @@ static void render_surface(struct wlr_surface *surface, static void render_view(struct roots_view *view, struct roots_desktop *desktop, struct wlr_output *wlr_output, struct timespec *when) { render_surface(view->wlr_surface, desktop, wlr_output, when, - view->x, view->y); + view->x, view->y, view->rotation); } static void output_frame_notify(struct wl_listener *listener, void *data) { From f9dbc1841d0a2b4a93cfb9a1783a34ebed426c59 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 3 Oct 2017 22:14:25 +0200 Subject: [PATCH 03/20] rootston: add meta-key to config file --- include/rootston/config.h | 4 +++ rootston/config.c | 50 ++++++++++++++++++++++++----------- rootston/cursor.c | 11 +++++--- rootston/rootston.ini.example | 5 +++- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/include/rootston/config.h b/include/rootston/config.h index ece11829..545b6742 100644 --- a/include/rootston/config.h +++ b/include/rootston/config.h @@ -33,6 +33,10 @@ struct roots_config { struct wlr_box *mapped_box; } cursor; + struct { + uint32_t meta_key; + } keyboard; + struct wl_list outputs; struct wl_list devices; struct wl_list bindings; diff --git a/rootston/config.c b/rootston/config.c index 3a21aff3..d454c2d9 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -86,6 +86,28 @@ invalid_input: return NULL; } +static uint32_t parse_modifier(const char *symname) { + if (strcmp(symname, "Shift") == 0) { + return WLR_MODIFIER_SHIFT; + } else if (strcmp(symname, "Caps") == 0) { + return WLR_MODIFIER_CAPS; + } else if (strcmp(symname, "Ctrl") == 0) { + return WLR_MODIFIER_CTRL; + } else if (strcmp(symname, "Alt") == 0) { + return WLR_MODIFIER_ALT; + } else if (strcmp(symname, "Mod2") == 0) { + return WLR_MODIFIER_MOD2; + } else if (strcmp(symname, "Mod3") == 0) { + return WLR_MODIFIER_MOD3; + } else if (strcmp(symname, "Logo") == 0) { + return WLR_MODIFIER_LOGO; + } else if (strcmp(symname, "Mod5") == 0) { + return WLR_MODIFIER_MOD5; + } else { + return 0; + } +} + static const char *output_prefix = "output:"; static const char *device_prefix = "device:"; @@ -171,6 +193,15 @@ static int config_ini_handler(void *user, const char *section, const char *name, } else { wlr_log(L_ERROR, "got unknown device config: %s", name); } + } else if (strcmp(section, "keyboard") == 0) { + if (strcmp(name, "meta-key") == 0) { + config->keyboard.meta_key = parse_modifier(value); + if (config->keyboard.meta_key == 0) { + wlr_log(L_ERROR, "got unknown meta key: %s", name); + } + } else { + wlr_log(L_ERROR, "got unknown keyboard config: %s", name); + } } else if (strcmp(section, "bindings") == 0) { struct binding_config *bc = calloc(1, sizeof(struct binding_config)); wl_list_insert(&config->bindings, &bc->link); @@ -190,22 +221,9 @@ static int config_ini_handler(void *user, const char *section, const char *name, bc->keysyms = calloc(1, keysyms_len * sizeof(xkb_keysym_t)); char *symname = symnames; for (size_t i = 0; i < keysyms_len; i++) { - if (strcmp(symname, "Shift") == 0) { - bc->modifiers |= WLR_MODIFIER_SHIFT; - } else if (strcmp(symname, "Caps") == 0) { - bc->modifiers |= WLR_MODIFIER_CAPS; - } else if (strcmp(symname, "Ctrl") == 0) { - bc->modifiers |= WLR_MODIFIER_CTRL; - } else if (strcmp(symname, "Alt") == 0) { - bc->modifiers |= WLR_MODIFIER_ALT; - } else if (strcmp(symname, "Mod2") == 0) { - bc->modifiers |= WLR_MODIFIER_MOD2; - } else if (strcmp(symname, "Mod3") == 0) { - bc->modifiers |= WLR_MODIFIER_MOD3; - } else if (strcmp(symname, "Logo") == 0) { - bc->modifiers |= WLR_MODIFIER_LOGO; - } else if (strcmp(symname, "Mod5") == 0) { - bc->modifiers |= WLR_MODIFIER_MOD5; + uint32_t modifier = parse_modifier(symname); + if (modifier != 0) { + bc->modifiers |= modifier; } else { xkb_keysym_t sym = xkb_keysym_from_name(symname, XKB_KEYSYM_NO_FLAGS); diff --git a/rootston/cursor.c b/rootston/cursor.c index 00218064..c26ca43a 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -166,12 +166,17 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { event->orientation, event->delta); } -static bool is_logo_pressed(struct roots_input *input) { +static bool is_meta_pressed(struct roots_input *input) { + uint32_t meta_key = input->server->config->keyboard.meta_key; + if (meta_key == 0) { + return false; + } + struct roots_keyboard *keyboard; wl_list_for_each(keyboard, &input->keyboards, link) { uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if ((modifiers ^ WLR_MODIFIER_LOGO) == 0) { + if ((modifiers ^ meta_key) == 0) { return true; } } @@ -187,7 +192,7 @@ static void do_cursor_button_press(struct roots_input *input, struct roots_view *view = view_at(desktop, input->cursor->x, input->cursor->y, &surface, &sx, &sy); - if (state == WLR_BUTTON_PRESSED && view && is_logo_pressed(input)) { + if (state == WLR_BUTTON_PRESSED && view && is_meta_pressed(input)) { set_view_focus(input, desktop, view); switch (button) { diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 8dd51ea2..9960cae1 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -25,8 +25,11 @@ map-to-output = VGA-1 # Restrict cursor movements for this mouse to concrete rectangle geometry = 2500x800 +[keyboard] +meta-key = Logo + # Keybindings # Maps key combinations with commands to execute # The special command "exit" stops the compositor [bindings] -Logo+q=exit +Logo+q = exit From dd4bdf1f56ab8b94da834cf8d3100e9baae9a2ea Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Tue, 3 Oct 2017 22:42:10 -0600 Subject: [PATCH 04/20] Unset $DISPLAY until XWayland is ready --- xwayland/xwayland.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index d3bb41a0..2bec1b63 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -215,6 +215,10 @@ static bool wlr_xwayland_init(struct wlr_xwayland *wlr_xwayland, wlr_xwayland_finish(wlr_xwayland); return false; } + + // unset $DISPLAY while XWayland starts + unsetenv("DISPLAY"); + wlr_xwayland->wl_fd[0] = -1; /* not ours anymore */ wlr_xwayland->destroy_listener.notify = xwayland_destroy_event; From dd07618727bab35daf1e561d40485ec568535ea5 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 4 Oct 2017 21:05:00 +0200 Subject: [PATCH 05/20] rootston: rotate cursor coordinates --- rootston/desktop.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index 8d1d34d6..a216f7f9 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -105,9 +106,18 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, struct wlr_box box; view_get_input_bounds(view, &box); - box.x += view->x; - box.y += view->y; - if (wlr_box_contains_point(&box, lx, ly)) { + if (view->rotation != 0.0) { + // Coordinates relative to the center of the view + double ox = view_sx - (double)box.width/2, + oy = view_sy - (double)box.height/2; + // Rotated coordinates + double rx = cos(view->rotation)*ox - sin(view->rotation)*oy, + ry = cos(view->rotation)*oy + sin(view->rotation)*ox; + view_sx = (double)box.width/2 + rx; + view_sy = (double)box.height/2 + ry; + } + + if (wlr_box_contains_point(&box, view_sx, view_sy)) { *sx = view_sx; *sy = view_sy; *surface = view->wlr_surface; From 09a6d863cf9b6e7fba459ede2b9769e78535b11a Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 4 Oct 2017 21:17:16 +0200 Subject: [PATCH 06/20] rootston: fix cursor coordinates for rotated subsurfaces --- rootston/desktop.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index a216f7f9..1e7d1171 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -93,17 +93,6 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, double view_sx = lx - view->x; double view_sy = ly - view->y; - double sub_x, sub_y; - struct wlr_subsurface *subsurface = - subsurface_at(view->wlr_surface, view_sx, view_sy, &sub_x, &sub_y); - - if (subsurface) { - *sx = view_sx - sub_x; - *sy = view_sy - sub_y; - *surface = subsurface->surface; - return view; - } - struct wlr_box box; view_get_input_bounds(view, &box); if (view->rotation != 0.0) { @@ -117,6 +106,16 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, view_sy = (double)box.height/2 + ry; } + double sub_x, sub_y; + struct wlr_subsurface *subsurface = + subsurface_at(view->wlr_surface, view_sx, view_sy, &sub_x, &sub_y); + if (subsurface) { + *sx = view_sx - sub_x; + *sy = view_sy - sub_y; + *surface = subsurface->surface; + return view; + } + if (wlr_box_contains_point(&box, view_sx, view_sy)) { *sx = view_sx; *sy = view_sy; From 3b226ba81a4fd5217dcc2004d30a82e97fddbf17 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 4 Oct 2017 22:01:54 +0200 Subject: [PATCH 07/20] rootston: rotation by steps --- rootston/cursor.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rootston/cursor.c b/rootston/cursor.c index c26ca43a..aad6751e 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -1,3 +1,4 @@ +#define _XOPEN_SOURCE 500 #include #include #include @@ -114,6 +115,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) { int vx = input->cursor->x - ox, vy = input->cursor->y - oy; float angle = atan2(vx*uy - vy*ux, vx*ux + vy*uy); + int steps = 12; + angle = round(angle/M_PI*steps) / (steps/M_PI); view->rotation = input->view_rotation + angle; } break; From 1a775adbde0ba81e6dcd2878a660a1386a8f972f Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 4 Oct 2017 23:05:57 +0200 Subject: [PATCH 08/20] rootston: fix rotated subsurfaces --- rootston/desktop.c | 4 ++-- rootston/output.c | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/rootston/desktop.c b/rootston/desktop.c index 1e7d1171..f99afaf5 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -102,8 +102,8 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly, // Rotated coordinates double rx = cos(view->rotation)*ox - sin(view->rotation)*oy, ry = cos(view->rotation)*oy + sin(view->rotation)*ox; - view_sx = (double)box.width/2 + rx; - view_sy = (double)box.height/2 + ry; + view_sx = rx + (double)box.width/2; + view_sy = ry + (double)box.height/2; } double sub_x, sub_y; diff --git a/rootston/output.c b/rootston/output.c index b3cbaf10..a1882f3d 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -56,9 +56,24 @@ static void render_surface(struct wlr_surface *surface, struct wlr_subsurface *subsurface; wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) { + double sx = subsurface->surface->current->subsurface_position.x, + sy = subsurface->surface->current->subsurface_position.y; + double sw = subsurface->surface->current->buffer_width, + sh = subsurface->surface->current->buffer_height; + if (rotation != 0.0) { + // Coordinates relative to the center of the subsurface + double ox = sx - (double)width/2 + sw/2, + oy = sy - (double)height/2 + sh/2; + // Rotated coordinates + double rx = cos(-rotation)*ox - sin(-rotation)*oy, + ry = cos(-rotation)*oy + sin(-rotation)*ox; + sx = rx + (double)width/2 - sw/2; + sy = ry + (double)height/2 - sh/2; + } + render_surface(subsurface->surface, desktop, wlr_output, when, - lx + subsurface->surface->current->subsurface_position.x, - ly + subsurface->surface->current->subsurface_position.y, + lx + sx, + ly + sy, rotation); } } From 134f708c55be1ce05bcf572dcef2f76da27be5c4 Mon Sep 17 00:00:00 2001 From: Versus Void Date: Thu, 5 Oct 2017 19:02:18 +0000 Subject: [PATCH 09/20] Fix double free --- types/wlr_seat.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/types/wlr_seat.c b/types/wlr_seat.c index 2d0bb01c..bb24fa15 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -262,6 +262,8 @@ static void pointer_surface_destroy_notify(struct wl_listener *listener, void *data) { struct wlr_seat_pointer_state *state = wl_container_of( listener, state, surface_destroy); + wl_list_remove(&state->surface_destroy.link); + wl_list_init(&state->surface_destroy.link); state->focused_surface = NULL; wlr_seat_pointer_clear_focus(state->wlr_seat); } @@ -270,6 +272,8 @@ static void pointer_resource_destroy_notify(struct wl_listener *listener, void *data) { struct wlr_seat_pointer_state *state = wl_container_of( listener, state, resource_destroy); + wl_list_remove(&state->resource_destroy.link); + wl_list_init(&state->resource_destroy.link); state->focused_surface = NULL; wlr_seat_pointer_clear_focus(state->wlr_seat); } @@ -499,6 +503,8 @@ static void keyboard_surface_destroy_notify(struct wl_listener *listener, void *data) { struct wlr_seat_keyboard_state *state = wl_container_of( listener, state, surface_destroy); + wl_list_remove(&state->surface_destroy.link); + wl_list_init(&state->surface_destroy.link); state->focused_surface = NULL; wlr_seat_keyboard_clear_focus(state->wlr_seat); } @@ -507,6 +513,8 @@ static void keyboard_resource_destroy_notify(struct wl_listener *listener, void *data) { struct wlr_seat_keyboard_state *state = wl_container_of( listener, state, resource_destroy); + wl_list_remove(&state->resource_destroy.link); + wl_list_init(&state->resource_destroy.link); state->focused_surface = NULL; wlr_seat_keyboard_clear_focus(state->wlr_seat); } From c5df6ca900cb445b88ede7e0ea3bb3a9042b5b6f Mon Sep 17 00:00:00 2001 From: Versus Void Date: Thu, 5 Oct 2017 20:01:56 +0000 Subject: [PATCH 10/20] Fix memory leaks --- backend/drm/backend.c | 2 +- backend/drm/drm.c | 13 +++++++++++++ include/rootston/desktop.h | 1 - include/rootston/input.h | 1 + render/gles2/renderer.c | 1 + rootston/input.c | 5 ++--- rootston/main.c | 1 + rootston/output.c | 1 - xwayland/xwm.c | 4 ++++ 9 files changed, 23 insertions(+), 6 deletions(-) diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 468fca6e..d7e2e616 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -34,8 +34,8 @@ static void wlr_drm_backend_destroy(struct wlr_backend *backend) { wlr_output_destroy(&conn->output); } - wlr_drm_renderer_finish(&drm->renderer); wlr_drm_resources_free(drm); + wlr_drm_renderer_finish(&drm->renderer); wlr_session_close_file(drm->session, drm->fd); wl_event_source_remove(drm->drm_event); list_free(drm->outputs); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 1a5fea9f..fc376b54 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -169,6 +169,19 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } } + for (size_t i = 0; i < drm->num_planes; ++i) { + struct wlr_drm_plane *plane = &drm->planes[i]; + if (plane->cursor_bo) { + gbm_bo_destroy(plane->cursor_bo); + } + if (plane->wlr_tex) { + wlr_texture_destroy(plane->wlr_tex); + } + if (plane->wlr_rend) { + wlr_renderer_destroy(plane->wlr_rend); + } + } + free(drm->crtcs); free(drm->planes); } diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 91ac87b7..0d641848 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -16,7 +16,6 @@ struct roots_output { struct roots_desktop *desktop; struct wlr_output *wlr_output; struct wl_listener frame; - struct wl_listener resolution; struct timespec last_frame; struct wl_list link; }; diff --git a/include/rootston/input.h b/include/rootston/input.h index 6161eb7a..f7cd2929 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -76,6 +76,7 @@ struct roots_input { // TODO: multiseat, multicursor struct wlr_cursor *cursor; + struct wlr_xcursor_theme *theme; struct wlr_xcursor *xcursor; struct wlr_seat *wl_seat; diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index f0c724e4..d6c22ebe 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -95,6 +95,7 @@ static void init_default_shaders() { } wlr_log(L_DEBUG, "Compiled default shaders"); + shaders.initialized = true; return; error: wlr_log(L_ERROR, "Failed to set up default shaders!"); diff --git a/rootston/input.c b/rootston/input.c index 9700b840..86a87e24 100644 --- a/rootston/input.c +++ b/rootston/input.c @@ -79,9 +79,8 @@ struct roots_input *input_create(struct roots_server *server, input->config = config; input->server = server; - struct wlr_xcursor_theme *theme; - assert(theme = wlr_xcursor_theme_load("default", 16)); - assert(input->xcursor = wlr_xcursor_theme_get_cursor(theme, "left_ptr")); + assert(input->theme = wlr_xcursor_theme_load("default", 16)); + assert(input->xcursor = wlr_xcursor_theme_get_cursor(input->theme, "left_ptr")); assert(input->wl_seat = wlr_seat_create(server->wl_display, "seat0")); wlr_seat_set_capabilities(input->wl_seat, WL_SEAT_CAPABILITY_KEYBOARD diff --git a/rootston/main.c b/rootston/main.c index 65a06a2f..5a60000c 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -43,5 +43,6 @@ int main(int argc, char **argv) { setenv("WAYLAND_DISPLAY", socket, true); wl_display_run(server.wl_display); + wlr_backend_destroy(server.backend); return 0; } diff --git a/rootston/output.c b/rootston/output.c index 14d1783e..bbc957aa 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -147,6 +147,5 @@ void output_remove_notify(struct wl_listener *listener, void *data) { // sample->compositor); wl_list_remove(&output->link); wl_list_remove(&output->frame.link); - wl_list_remove(&output->resolution.link); free(output); } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 2038ff0f..39989672 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -83,6 +83,10 @@ static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) { } list_free(surface->state); free(surface->window_type); + free(surface->protocols); + free(surface->class); + free(surface->instance); + free(surface->title); free(surface); } From 0c22ad09a7f4673b533c70f5a9a6bfcb523eba3a Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 2 Oct 2017 17:34:55 +0200 Subject: [PATCH 11/20] xwayland: request hints --- xwayland/xwm.c | 27 +++++++++++++++++++++++++++ xwayland/xwm.h | 3 +++ 2 files changed, 30 insertions(+) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 39989672..7030442b 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -12,6 +12,9 @@ const char *atom_map[ATOM_LAST] = { "WL_SURFACE_ID", "WM_DELETE_WINDOW", "WM_PROTOCOLS", + "WM_NORMAL_HINTS", + "WM_SIZE_HINTS", + "_MOTIF_WM_HINTS", "UTF8_STRING", "WM_S0", "_NET_SUPPORTED", @@ -269,6 +272,24 @@ static void read_surface_protocols(struct wlr_xwm *xwm, wlr_log(L_DEBUG, "WM_PROTOCOLS (%zu)", atoms_len); } +static void read_surface_normal_hints(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { + if (reply->type != xwm->atoms[WM_SIZE_HINTS]) { + return; + } + + // TODO: xcb_icccm_get_wm_size_hints_from_reply + // See https://github.com/i3/i3/blob/55bc6741796e8b179b6111a721a3e9631934bb86/src/handlers.c#L994 + + wlr_log(L_DEBUG, "WM_NORMAL_HINTS (%d)", reply->value_len); +} + +static void read_surface_motif_hints(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { + // TODO + wlr_log(L_DEBUG, "MOTIF_WM_HINTS (%d)", reply->value_len); +} + static void read_surface_property(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_atom_t property) { xcb_get_property_cookie_t cookie = xcb_get_property(xwm->xcb_conn, 0, @@ -294,6 +315,10 @@ static void read_surface_property(struct wlr_xwm *xwm, read_surface_protocols(xwm, surface, reply); } else if (property == xwm->atoms[NET_WM_STATE]) { read_surface_state(xwm, surface, reply); + } else if (property == xwm->atoms[WM_NORMAL_HINTS]) { + read_surface_normal_hints(xwm, surface, reply); + } else if (property == xwm->atoms[MOTIF_WM_HINTS]) { + read_surface_motif_hints(xwm, surface, reply); } else { wlr_log(L_DEBUG, "unhandled x11 property %u", property); } @@ -313,6 +338,8 @@ static void map_shell_surface(struct wlr_xwm *xwm, XCB_ATOM_WM_NAME, XCB_ATOM_WM_TRANSIENT_FOR, xwm->atoms[WM_PROTOCOLS], + xwm->atoms[WM_NORMAL_HINTS], + xwm->atoms[MOTIF_WM_HINTS], xwm->atoms[NET_WM_STATE], xwm->atoms[NET_WM_WINDOW_TYPE], xwm->atoms[NET_WM_NAME], diff --git a/xwayland/xwm.h b/xwayland/xwm.h index d1998e48..48504602 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -49,6 +49,9 @@ enum atom_name { WL_SURFACE_ID, WM_DELETE_WINDOW, WM_PROTOCOLS, + WM_NORMAL_HINTS, + WM_SIZE_HINTS, + MOTIF_WM_HINTS, UTF8_STRING, WM_S0, NET_SUPPORTED, From ef5914bdb61e788cf3b62378c4e7a14d8bf0430f Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 11:47:58 +0200 Subject: [PATCH 12/20] xwayland: add wlr_xwayland_surface->motif_hints --- include/wlr/xwayland.h | 2 ++ xwayland/xwm.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 3525ff3b..dc9798b2 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -53,6 +53,8 @@ struct wlr_xwayland_surface { xcb_atom_t *protocols; size_t protocols_len; + uint32_t motif_hints[5]; + struct { struct wl_signal destroy; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 7030442b..f97f0a8e 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -286,7 +286,13 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, static void read_surface_motif_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { - // TODO + if (reply->value_len < 5) { + return; + } + + uint32_t *motif_hints = xcb_get_property_value(reply); + memcpy(surface->motif_hints, motif_hints, sizeof(surface->motif_hints)); + wlr_log(L_DEBUG, "MOTIF_WM_HINTS (%d)", reply->value_len); } From ed9796ec683b64655c60b09f0c9969263f4394d6 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 12:32:12 +0200 Subject: [PATCH 13/20] xwayland: parse normal hints --- include/wlr/xwayland.h | 7 +++++++ meson.build | 5 +++++ xwayland/meson.build | 2 +- xwayland/xwm.c | 14 ++++++++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index dc9798b2..181259fa 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -6,6 +6,10 @@ #include #include +#ifdef HAS_XCB_ICCCM + #include +#endif + struct wlr_xwm; struct wlr_xwayland { @@ -54,6 +58,9 @@ struct wlr_xwayland_surface { size_t protocols_len; uint32_t motif_hints[5]; + #ifdef HAS_XCB_ICCCM + xcb_size_hints_t size_hints; + #endif struct { struct wl_signal destroy; diff --git a/meson.build b/meson.build index 520eceb9..57c26b0f 100644 --- a/meson.build +++ b/meson.build @@ -45,12 +45,17 @@ udev = dependency('libudev') pixman = dependency('pixman-1') xcb = dependency('xcb') xcb_composite = dependency('xcb-composite') +xcb_icccm = dependency('xcb-icccm', required: false) x11_xcb = dependency('x11-xcb') libcap = dependency('libcap', required: false) systemd = dependency('libsystemd', required: false) elogind = dependency('libelogind', required: false) math = cc.find_library('m', required: false) +if xcb_icccm.found() + add_project_arguments('-DHAS_XCB_ICCCM', language: 'c') +endif + if libcap.found() and get_option('enable_libcap') add_project_arguments('-DHAS_LIBCAP', language: 'c') endif diff --git a/xwayland/meson.build b/xwayland/meson.build index 9797a1a1..d989f6dd 100644 --- a/xwayland/meson.build +++ b/xwayland/meson.build @@ -6,5 +6,5 @@ lib_wlr_xwayland = static_library( 'xwm.c', ), include_directories: wlr_inc, - dependencies: [wayland_server, xcb, xcb_composite, pixman], + dependencies: [wayland_server, xcb, xcb_composite, xcb_icccm, pixman], ) diff --git a/xwayland/xwm.c b/xwayland/xwm.c index f97f0a8e..afd4ef29 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -8,6 +8,10 @@ #include "wlr/xwayland.h" #include "xwm.h" +#ifdef HAS_XCB_ICCCM + #include +#endif + const char *atom_map[ATOM_LAST] = { "WL_SURFACE_ID", "WM_DELETE_WINDOW", @@ -272,17 +276,23 @@ static void read_surface_protocols(struct wlr_xwm *xwm, wlr_log(L_DEBUG, "WM_PROTOCOLS (%zu)", atoms_len); } +#ifdef HAS_XCB_ICCCM static void read_surface_normal_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { if (reply->type != xwm->atoms[WM_SIZE_HINTS]) { return; } - // TODO: xcb_icccm_get_wm_size_hints_from_reply - // See https://github.com/i3/i3/blob/55bc6741796e8b179b6111a721a3e9631934bb86/src/handlers.c#L994 + xcb_icccm_get_wm_size_hints_from_reply(&surface->size_hints, reply); wlr_log(L_DEBUG, "WM_NORMAL_HINTS (%d)", reply->value_len); } +#else +static void read_surface_normal_hints(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { + // Do nothing +} +#endif static void read_surface_motif_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { From ca68ef37f056562206b0c4b0442cbfedc8a5e5f3 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 15:42:16 +0200 Subject: [PATCH 14/20] Add padding if xcb_icccm is not available --- include/wlr/xwayland.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 181259fa..3cbaee59 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -60,6 +60,8 @@ struct wlr_xwayland_surface { uint32_t motif_hints[5]; #ifdef HAS_XCB_ICCCM xcb_size_hints_t size_hints; + #else + char size_hints_padding[72]; #endif struct { From 267f24753f010e6ac7e49f7bfb27a9c85f40b62d Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 16:24:45 +0200 Subject: [PATCH 15/20] Add support for WM_HINTS --- include/wlr/xwayland.h | 2 ++ xwayland/xwm.c | 26 +++++++++++++++++++++++++- xwayland/xwm.h | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 3cbaee59..73df1ea9 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -59,8 +59,10 @@ struct wlr_xwayland_surface { uint32_t motif_hints[5]; #ifdef HAS_XCB_ICCCM + xcb_icccm_wm_hints_t hints; xcb_size_hints_t size_hints; #else + char hints_padding[36]; char size_hints_padding[72]; #endif diff --git a/xwayland/xwm.c b/xwayland/xwm.c index afd4ef29..bc930140 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -15,6 +15,7 @@ const char *atom_map[ATOM_LAST] = { "WL_SURFACE_ID", "WM_DELETE_WINDOW", + "WM_HINTS", "WM_PROTOCOLS", "WM_NORMAL_HINTS", "WM_SIZE_HINTS", @@ -276,10 +277,30 @@ static void read_surface_protocols(struct wlr_xwm *xwm, wlr_log(L_DEBUG, "WM_PROTOCOLS (%zu)", atoms_len); } +#ifdef HAS_XCB_ICCCM +static void read_surface_hints(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { + // According to the docs, reply->type == xwm->atoms[WM_HINTS] + // In practice, reply->type == XCB_ATOM_ATOM + if (reply->value_len == 0) { + return; + } + + xcb_icccm_get_wm_hints_from_reply(&surface->hints, reply); + + wlr_log(L_DEBUG, "WM_HINTS (%d)", reply->value_len); +} +#else +static void read_surface_hints(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { + // Do nothing +} +#endif + #ifdef HAS_XCB_ICCCM static void read_surface_normal_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { - if (reply->type != xwm->atoms[WM_SIZE_HINTS]) { + if (reply->type != xwm->atoms[WM_SIZE_HINTS] || reply->value_len == 0) { return; } @@ -331,6 +352,8 @@ static void read_surface_property(struct wlr_xwm *xwm, read_surface_protocols(xwm, surface, reply); } else if (property == xwm->atoms[NET_WM_STATE]) { read_surface_state(xwm, surface, reply); + } else if (property == xwm->atoms[WM_HINTS]) { + read_surface_hints(xwm, surface, reply); } else if (property == xwm->atoms[WM_NORMAL_HINTS]) { read_surface_normal_hints(xwm, surface, reply); } else if (property == xwm->atoms[MOTIF_WM_HINTS]) { @@ -354,6 +377,7 @@ static void map_shell_surface(struct wlr_xwm *xwm, XCB_ATOM_WM_NAME, XCB_ATOM_WM_TRANSIENT_FOR, xwm->atoms[WM_PROTOCOLS], + xwm->atoms[WM_HINTS], xwm->atoms[WM_NORMAL_HINTS], xwm->atoms[MOTIF_WM_HINTS], xwm->atoms[NET_WM_STATE], diff --git a/xwayland/xwm.h b/xwayland/xwm.h index 48504602..be710a1b 100644 --- a/xwayland/xwm.h +++ b/xwayland/xwm.h @@ -49,6 +49,7 @@ enum atom_name { WL_SURFACE_ID, WM_DELETE_WINDOW, WM_PROTOCOLS, + WM_HINTS, WM_NORMAL_HINTS, WM_SIZE_HINTS, MOTIF_WM_HINTS, From fc61e827953479037bd3408a2ff14fa894bcfde1 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 16:32:05 +0200 Subject: [PATCH 16/20] Use pointers for xwayland hints and size_hints --- include/wlr/xwayland.h | 8 ++++---- xwayland/xwm.c | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 73df1ea9..05453c21 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -59,11 +59,11 @@ struct wlr_xwayland_surface { uint32_t motif_hints[5]; #ifdef HAS_XCB_ICCCM - xcb_icccm_wm_hints_t hints; - xcb_size_hints_t size_hints; + xcb_icccm_wm_hints_t *hints; + xcb_size_hints_t *size_hints; #else - char hints_padding[36]; - char size_hints_padding[72]; + void *hints; + void *size_hints; #endif struct { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index bc930140..2ac24260 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -89,12 +89,14 @@ static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) { for (size_t i = 0; i < surface->state->length; i++) { free(surface->state->items[i]); } + free(surface->title); + free(surface->class); + free(surface->instance); list_free(surface->state); free(surface->window_type); free(surface->protocols); - free(surface->class); - free(surface->instance); - free(surface->title); + free(surface->hints); + free(surface->size_hints); free(surface); } @@ -286,7 +288,12 @@ static void read_surface_hints(struct wlr_xwm *xwm, return; } - xcb_icccm_get_wm_hints_from_reply(&surface->hints, reply); + free(surface->hints); + surface->hints = calloc(1, sizeof(xcb_icccm_wm_hints_t)); + if (surface->hints == NULL) { + return; + } + xcb_icccm_get_wm_hints_from_reply(surface->hints, reply); wlr_log(L_DEBUG, "WM_HINTS (%d)", reply->value_len); } @@ -304,7 +311,12 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, return; } - xcb_icccm_get_wm_size_hints_from_reply(&surface->size_hints, reply); + free(surface->size_hints); + surface->size_hints = calloc(1, sizeof(xcb_size_hints_t)); + if (surface->size_hints == NULL) { + return; + } + xcb_icccm_get_wm_size_hints_from_reply(surface->size_hints, reply); wlr_log(L_DEBUG, "WM_NORMAL_HINTS (%d)", reply->value_len); } From 454a6a902b7e78576fa77e77395cbd26901b18e2 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 16:49:47 +0200 Subject: [PATCH 17/20] Parse _MOTIF_HINTS --- include/wlr/xwayland.h | 9 ++++++++- xwayland/xwm.c | 25 ++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 05453c21..1f2d7acb 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -33,6 +33,12 @@ struct wlr_xwayland { void *data; }; +enum wlr_xwayland_surface_decorations { + WLR_XWAYLAND_SURFACE_DECORATIONS_ALL = 0, + WLR_XWAYLAND_SURFACE_DECORATIONS_NO_BORDER = 1, + WLR_XWAYLAND_SURFACE_DECORATIONS_NO_TITLE = 2, +}; + struct wlr_xwayland_surface { xcb_window_t window_id; uint32_t surface_id; @@ -57,7 +63,8 @@ struct wlr_xwayland_surface { xcb_atom_t *protocols; size_t protocols_len; - uint32_t motif_hints[5]; + uint32_t decorations; + #ifdef HAS_XCB_ICCCM xcb_icccm_wm_hints_t *hints; xcb_size_hints_t *size_hints; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 2ac24260..120c1ae8 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -327,6 +327,16 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, } #endif + +#define MWM_HINTS_FLAGS_FIELD 0 +#define MWM_HINTS_DECORATIONS_FIELD 2 + +#define MWM_HINTS_DECORATIONS (1 << 1) + +#define MWM_DECOR_ALL (1 << 0) +#define MWM_DECOR_BORDER (1 << 1) +#define MWM_DECOR_TITLE (1 << 3) + static void read_surface_motif_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) { if (reply->value_len < 5) { @@ -334,7 +344,20 @@ static void read_surface_motif_hints(struct wlr_xwm *xwm, } uint32_t *motif_hints = xcb_get_property_value(reply); - memcpy(surface->motif_hints, motif_hints, sizeof(surface->motif_hints)); + if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { + surface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; + uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; + if ((decorations & MWM_DECOR_ALL) == 0) { + if ((decorations & MWM_DECOR_BORDER) == 0) { + surface->decorations |= + WLR_XWAYLAND_SURFACE_DECORATIONS_NO_BORDER; + } + if ((decorations & MWM_DECOR_TITLE) == 0) { + surface->decorations |= + WLR_XWAYLAND_SURFACE_DECORATIONS_NO_TITLE; + } + } + } wlr_log(L_DEBUG, "MOTIF_WM_HINTS (%d)", reply->value_len); } From 1b1346462e90b9e4e2be592feba000d616224317 Mon Sep 17 00:00:00 2001 From: Versus Void Date: Thu, 5 Oct 2017 21:30:31 +0000 Subject: [PATCH 18/20] Fix focusing null view --- rootston/cursor.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rootston/cursor.c b/rootston/cursor.c index aad6751e..eec8eb5d 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -128,6 +128,12 @@ static void set_view_focus(struct roots_input *input, if (input->active_view == view) { return; } + input->active_view = view; + input->mode = ROOTS_CURSOR_PASSTHROUGH; + if (!view) { + return; + } + size_t index = 0; for (size_t i = 0; i < desktop->views->length; ++i) { struct roots_view *_view = desktop->views->items[i]; @@ -136,8 +142,6 @@ static void set_view_focus(struct roots_input *input, index = i; } } - input->active_view = view; - input->mode = ROOTS_CURSOR_PASSTHROUGH; // TODO: list_swap list_del(desktop->views, index); list_add(desktop->views, view); @@ -219,8 +223,7 @@ static void do_cursor_button_press(struct roots_input *input, int i; switch (state) { case WLR_BUTTON_RELEASED: - input->active_view = NULL; - input->mode = ROOTS_CURSOR_PASSTHROUGH; + set_view_focus(input, desktop, NULL); break; case WLR_BUTTON_PRESSED: i = input->input_events_idx; From 7d57c1463da61ff16784e6b756356720a0af185c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 5 Oct 2017 14:55:55 -0400 Subject: [PATCH 19/20] Fix #210 --- rootston/output.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index 1d5ef98b..d7aade3d 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -32,15 +32,14 @@ static void render_surface(struct wlr_surface *surface, float translate_origin[16]; wlr_matrix_translate(&translate_origin, - ox + width/2, oy + height/2, 0); + (int)ox + width / 2, (int)oy + height / 2, 0); float rotate[16]; wlr_matrix_rotate(&rotate, rotation); float translate_center[16]; - wlr_matrix_translate(&translate_center, -width/2, -height/2, 0); + wlr_matrix_translate(&translate_center, -width / 2, -height / 2, 0); float transform[16]; wlr_matrix_mul(&translate_origin, &rotate, &transform); wlr_matrix_mul(&transform, &translate_center, &transform); - wlr_surface_get_matrix(surface, &matrix, &wlr_output->transform_matrix, &transform); wlr_render_with_matrix(desktop->server->renderer, From 12b9b1a4bdf00742cc510c2329c7a66c649b3ab0 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 5 Oct 2017 22:23:37 +0200 Subject: [PATCH 20/20] Copy xcb_icccm structs into wlroots --- include/wlr/xwayland.h | 35 +++++++++++++++++++++++++++-------- xwayland/xwm.c | 17 +++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 1f2d7acb..09f9fbac 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -39,6 +39,30 @@ enum wlr_xwayland_surface_decorations { WLR_XWAYLAND_SURFACE_DECORATIONS_NO_TITLE = 2, }; +struct wlr_xwayland_surface_hints { + uint32_t flags; + uint32_t input; + int32_t initial_state; + xcb_pixmap_t icon_pixmap; + xcb_window_t icon_window; + int32_t icon_x, icon_y; + xcb_pixmap_t icon_mask; + xcb_window_t window_group; +}; + +struct wlr_xwayland_surface_size_hints { + uint32_t flags; + int32_t x, y; + int32_t width, height; + int32_t min_width, min_height; + int32_t max_width, max_height; + int32_t width_inc, height_inc; + int32_t base_width, base_height; + int32_t min_aspect_num, min_aspect_den; + int32_t max_aspect_num, max_aspect_den; + uint32_t win_gravity; +}; + struct wlr_xwayland_surface { xcb_window_t window_id; uint32_t surface_id; @@ -64,14 +88,9 @@ struct wlr_xwayland_surface { size_t protocols_len; uint32_t decorations; - - #ifdef HAS_XCB_ICCCM - xcb_icccm_wm_hints_t *hints; - xcb_size_hints_t *size_hints; - #else - void *hints; - void *size_hints; - #endif + struct wlr_xwayland_surface_hints *hints; + uint32_t hints_urgency; + struct wlr_xwayland_surface_size_hints *size_hints; struct { struct wl_signal destroy; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 120c1ae8..a4091d1f 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -288,12 +288,16 @@ static void read_surface_hints(struct wlr_xwm *xwm, return; } + xcb_icccm_wm_hints_t hints; + xcb_icccm_get_wm_hints_from_reply(&hints, reply); + free(surface->hints); - surface->hints = calloc(1, sizeof(xcb_icccm_wm_hints_t)); + surface->hints = calloc(1, sizeof(struct wlr_xwayland_surface_hints)); if (surface->hints == NULL) { return; } - xcb_icccm_get_wm_hints_from_reply(surface->hints, reply); + memcpy(surface->hints, &hints, sizeof(struct wlr_xwayland_surface_hints)); + surface->hints_urgency = xcb_icccm_wm_hints_get_urgency(&hints); wlr_log(L_DEBUG, "WM_HINTS (%d)", reply->value_len); } @@ -311,12 +315,17 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, return; } + xcb_size_hints_t size_hints; + xcb_icccm_get_wm_size_hints_from_reply(&size_hints, reply); + free(surface->size_hints); - surface->size_hints = calloc(1, sizeof(xcb_size_hints_t)); + surface->size_hints = + calloc(1, sizeof(struct wlr_xwayland_surface_size_hints)); if (surface->size_hints == NULL) { return; } - xcb_icccm_get_wm_size_hints_from_reply(surface->size_hints, reply); + memcpy(surface->size_hints, &size_hints, + sizeof(struct wlr_xwayland_surface_size_hints)); wlr_log(L_DEBUG, "WM_NORMAL_HINTS (%d)", reply->value_len); }