From 660a022909d62e51de42518806815ce446fc10f7 Mon Sep 17 00:00:00 2001 From: random human Date: Thu, 30 Aug 2018 22:23:28 +0530 Subject: [PATCH 01/12] Fixes examples/dmabuf-capture being built with unmet dependencies Even if the libav* variables were disabler objects, the build targer dmabuf-capture was being built. Modified the script to support a generic solution. --- examples/meson.build | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/examples/meson.build b/examples/meson.build index 0fb37a9e..b5ad6c98 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -20,31 +20,31 @@ endif examples = { 'simple': { 'src': 'simple.c', - 'dep': wlroots, + 'dep': [wlroots], }, 'pointer': { 'src': 'pointer.c', - 'dep': wlroots, + 'dep': [wlroots], }, 'touch': { 'src': ['touch.c', 'cat.c'], - 'dep': wlroots, + 'dep': [wlroots], }, 'tablet': { 'src': 'tablet.c', - 'dep': wlroots, + 'dep': [wlroots], }, 'rotation': { 'src': ['rotation.c', 'cat.c'], - 'dep': wlroots, + 'dep': [wlroots], }, 'multi-pointer': { 'src': 'multi-pointer.c', - 'dep': wlroots, + 'dep': [wlroots], }, 'output-layout': { 'src': ['output-layout.c', 'cat.c'], - 'dep': wlroots, + 'dep': [wlroots], }, 'screenshot': { 'src': 'screenshot.c', @@ -93,10 +93,18 @@ examples = { } foreach name, info : examples - executable( - name, - info.get('src'), - dependencies: info.get('dep'), - build_by_default: get_option('examples'), - ) + all_dep_found = true + foreach d : info.get('dep') + all_dep_found = all_dep_found and d.found() + endforeach + if all_dep_found + executable( + name, + info.get('src'), + dependencies: info.get('dep'), + build_by_default: get_option('examples'), + ) + else + warning('Dependencies not satisfied for ' + name) + endif endforeach From 8589ae19de1d5699a586f96fe34a35c586e1e29c Mon Sep 17 00:00:00 2001 From: random human Date: Fri, 31 Aug 2018 16:11:46 +0530 Subject: [PATCH 02/12] Fix bugs listed by clang's static analyzer A few pedantic changes and unused variables (1-4), and genuine bugs (5, 6). The reports with the corresponding files and lines numbers are as follows. 1. backend/libinput/tablet_pad.c@31,44,57 "Allocator sizeof operand mismatch" "Result of 'calloc' is converted to a pointer of type 'unsigned int', which is incompatible with sizeof operand type 'int'" 2. types/tablet_v2/wlr_tablet_v2_pad.c@371 "Allocator sizeof operand mismatch" "Result of 'calloc' is converted to a pointer of type 'uint32_t', which is incompatible with sizeof operand type 'int'" 3. types/wlr_cursor.c@335 "Dead initialization" "Value stored to 'dx'/'dy' during its initialization is never read" 4. rootston/xdg_shell.c@510 "Dead initialization" "Value stored to 'desktop' during its initialization is never read" 5. types/tablet_v2/wlr_tablet_v2_pad.c@475 "Dereference of null pointer" "Access to field 'strips' results in a dereference of a null pointer (loaded from field 'current_client')" The boolean logic was incorrect (c.f. the check in the following function). 6. examples/idle.c@163,174,182 "Uninitialized argument value" "1st function call argument is an uninitialized value" If close_timeout != 0, but simulate_activity_timeout >= close_timeout, the program would segfault at pthread_cancel(t1). --- backend/libinput/tablet_pad.c | 6 +++--- examples/idle.c | 21 ++++++++++++++------- rootston/xdg_shell.c | 2 -- types/tablet_v2/wlr_tablet_v2_pad.c | 8 ++++---- types/wlr_cursor.c | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/backend/libinput/tablet_pad.c b/backend/libinput/tablet_pad.c index 579a11cf..0642f925 100644 --- a/backend/libinput/tablet_pad.c +++ b/backend/libinput/tablet_pad.c @@ -28,7 +28,7 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, ++group->ring_count; } } - group->rings = calloc(sizeof(int), group->ring_count); + group->rings = calloc(sizeof(unsigned int), group->ring_count); size_t ring = 0; for (size_t i = 0; i < pad->ring_count; ++i) { if (libinput_tablet_pad_mode_group_has_ring(li_group, i)) { @@ -41,7 +41,7 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, ++group->strip_count; } } - group->strips = calloc(sizeof(int), group->strip_count); + group->strips = calloc(sizeof(unsigned int), group->strip_count); size_t strip = 0; for (size_t i = 0; i < pad->strip_count; ++i) { if (libinput_tablet_pad_mode_group_has_strip(li_group, i)) { @@ -54,7 +54,7 @@ static void add_pad_group_from_libinput(struct wlr_tablet_pad *pad, ++group->button_count; } } - group->buttons = calloc(sizeof(int), group->button_count); + group->buttons = calloc(sizeof(unsigned int), group->button_count); size_t button = 0; for (size_t i = 0; i < pad->button_count; ++i) { if (libinput_tablet_pad_mode_group_has_button(li_group, i)) { diff --git a/examples/idle.c b/examples/idle.c index 30e106db..87a03924 100644 --- a/examples/idle.c +++ b/examples/idle.c @@ -152,14 +152,20 @@ int main(int argc, char *argv[]) { .display = display, }; - if (simulate_activity_timeout != 0 && simulate_activity_timeout < close_timeout) { + bool create_t1 = (simulate_activity_timeout != 0) && + (simulate_activity_timeout < close_timeout); + + if (create_t1) { if (pthread_create(&t1, NULL, &simulate_activity, (void *)&arg) != 0) { return -1; } } - if (close_timeout != 0) { + + bool create_t2 = (close_timeout != 0); + + if (create_t2) { if (pthread_create(&t2, NULL, &close_program, (void *)&arg) != 0) { - if (simulate_activity_timeout != 0) { + if (create_t1) { pthread_cancel(t1); } return -1; @@ -170,18 +176,19 @@ int main(int argc, char *argv[]) { fprintf(stdout, "waiting\n"); if (pthread_create(&t3, NULL, &main_loop, (void *)display) != 0) { - if (simulate_activity_timeout != 0) { + if (create_t1) { pthread_cancel(t1); } - if (close_timeout != 0 ) { + if (create_t2) { pthread_cancel(t2); } + return -1; } - if (simulate_activity_timeout != 0) { + if (create_t1) { pthread_join(t1, NULL); } - if (close_timeout != 0) { + if (create_t2) { pthread_join(t2, NULL); } pthread_cancel(t3); diff --git a/rootston/xdg_shell.c b/rootston/xdg_shell.c index fed9afcd..2cf2081e 100644 --- a/rootston/xdg_shell.c +++ b/rootston/xdg_shell.c @@ -507,8 +507,6 @@ static void decoration_handle_surface_commit(struct wl_listener *listener, } void handle_xdg_toplevel_decoration(struct wl_listener *listener, void *data) { - struct roots_desktop *desktop = - wl_container_of(listener, desktop, xdg_toplevel_decoration); struct wlr_xdg_toplevel_decoration_v1 *wlr_decoration = data; wlr_log(WLR_DEBUG, "new xdg toplevel decoration"); diff --git a/types/tablet_v2/wlr_tablet_v2_pad.c b/types/tablet_v2/wlr_tablet_v2_pad.c index 1fcfa38e..a1672d28 100644 --- a/types/tablet_v2/wlr_tablet_v2_pad.c +++ b/types/tablet_v2/wlr_tablet_v2_pad.c @@ -368,7 +368,7 @@ struct wlr_tablet_v2_tablet_pad *wlr_tablet_pad_create( } pad->group_count = wl_list_length(&wlr_pad->groups); - pad->groups = calloc(pad->group_count, sizeof(int)); + pad->groups = calloc(pad->group_count, sizeof(uint32_t)); if (!pad->groups) { free(pad); return NULL; @@ -471,9 +471,9 @@ void wlr_send_tablet_v2_tablet_pad_button( void wlr_send_tablet_v2_tablet_pad_strip(struct wlr_tablet_v2_tablet_pad *pad, uint32_t strip, double position, bool finger, uint32_t time) { - if (!pad->current_client && - pad->current_client->strips && - pad->current_client->strips[strip]) { + if (!pad->current_client || + !pad->current_client->strips || + !pad->current_client->strips[strip]) { return; } struct wl_resource *resource = pad->current_client->strips[strip]; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 82ad1a4a..19b3a51a 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -332,7 +332,7 @@ static void handle_pointer_motion(struct wl_listener *listener, void *data) { static void apply_output_transform(double *x, double *y, enum wl_output_transform transform) { - double dx = *x, dy = *y; + double dx, dy; double width = 1.0, height = 1.0; switch (transform) { From 6014ee50b3d6b093e292c25ef9af6b550efb357f Mon Sep 17 00:00:00 2001 From: random human Date: Fri, 31 Aug 2018 20:58:45 +0530 Subject: [PATCH 03/12] Add clang's static analyzer to build.yml --- .build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.build.yml b/.build.yml index 8b2f9c1f..4b3e197d 100644 --- a/.build.yml +++ b/.build.yml @@ -25,4 +25,4 @@ tasks: ninja - clang: | cd wlroots/build-clang - ninja + ninja scan-build From 62539e265e6930e055552a11092195848567a12b Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Fri, 31 Aug 2018 20:48:38 +0300 Subject: [PATCH 04/12] add missing wlr_box.h include in wlr_screencopy_v1.h --- include/wlr/types/wlr_screencopy_v1.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/wlr/types/wlr_screencopy_v1.h b/include/wlr/types/wlr_screencopy_v1.h index 822fb3d0..aba32a45 100644 --- a/include/wlr/types/wlr_screencopy_v1.h +++ b/include/wlr/types/wlr_screencopy_v1.h @@ -10,6 +10,7 @@ #define WLR_TYPES_WLR_SCREENCOPY_V1_H #include +#include struct wlr_screencopy_manager_v1 { struct wl_global *global; From e334b46b39ee38ac87da3f83b633a1c67091b7c3 Mon Sep 17 00:00:00 2001 From: Aidan Epstein Date: Fri, 31 Aug 2018 23:36:38 +0000 Subject: [PATCH 05/12] Fix uninitialized value in wlr_cursor. --- types/wlr_cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 19b3a51a..49f11b20 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -332,7 +332,7 @@ static void handle_pointer_motion(struct wl_listener *listener, void *data) { static void apply_output_transform(double *x, double *y, enum wl_output_transform transform) { - double dx, dy; + double dx = 0.0, dy = 0.0; double width = 1.0, height = 1.0; switch (transform) { From 472476ebcfd3c78ee136f9a465523c236295a049 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 1 Sep 2018 18:30:41 +0200 Subject: [PATCH 06/12] Do not modeset disabled outputs --- rootston/output.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rootston/output.c b/rootston/output.c index d8edf1c2..8677f491 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -822,12 +822,6 @@ void handle_new_output(struct wl_listener *listener, void *data) { wlr_output->model, wlr_output->serial, wlr_output->phys_width, wlr_output->phys_height); - if (!wl_list_empty(&wlr_output->modes)) { - struct wlr_output_mode *mode = - wl_container_of((&wlr_output->modes)->prev, mode, link); - wlr_output_set_mode(wlr_output, mode); - } - struct roots_output *output = calloc(1, sizeof(struct roots_output)); clock_gettime(CLOCK_MONOTONIC, &output->last_frame); output->desktop = desktop; @@ -856,22 +850,28 @@ void handle_new_output(struct wl_listener *listener, void *data) { struct roots_output_config *output_config = roots_config_get_output(config, wlr_output); + + if ((!output_config || output_config->enable) && !wl_list_empty(&wlr_output->modes)) { + struct wlr_output_mode *mode = + wl_container_of(wlr_output->modes.prev, mode, link); + wlr_output_set_mode(wlr_output, mode); + } + if (output_config) { if (output_config->enable) { - struct roots_output_mode_config *mode_config; - if (wlr_output_is_drm(wlr_output)) { + struct roots_output_mode_config *mode_config; wl_list_for_each(mode_config, &output_config->modes, link) { wlr_drm_connector_add_mode(wlr_output, &mode_config->info); } - } else { - if (!wl_list_empty(&output_config->modes)) { - wlr_log(WLR_ERROR, "Can only add modes for DRM backend"); - } + } else if (!wl_list_empty(&output_config->modes)) { + wlr_log(WLR_ERROR, "Can only add modes for DRM backend"); } + if (output_config->mode.width) { set_mode(wlr_output, output_config); } + wlr_output_set_scale(wlr_output, output_config->scale); wlr_output_set_transform(wlr_output, output_config->transform); wlr_output_layout_add(desktop->layout, wlr_output, output_config->x, From e84f01168d55087932529301bb8e1c723244b72b Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 1 Sep 2018 23:43:16 +0200 Subject: [PATCH 07/12] backend/drm: allow disabling outputs in NEEDS_MODESET state This correctly frees CRTCs when disabling outputs without setting a mode. --- backend/drm/drm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a666ce71..c1fa1992 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -344,7 +344,8 @@ static void drm_connector_start_renderer(struct wlr_drm_connector *conn) { void enable_drm_connector(struct wlr_output *output, bool enable) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; - if (conn->state != WLR_DRM_CONN_CONNECTED) { + if (conn->state != WLR_DRM_CONN_CONNECTED + && conn->state != WLR_DRM_CONN_NEEDS_MODESET) { return; } From ef88df214249b578b030e0cdd02153fde2bba848 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 2 Sep 2018 01:03:20 +0200 Subject: [PATCH 08/12] backend/drm: emit new_output after scanning connectors This prevents receiving modesetting requests from the compositor while we don't have the whole picture (ie. while we haven't yet scanned all connectors). This also makes connectors without CRTCs disabled (they can't be enabled yet even if some CRTCs are free'd -- this is future work). --- backend/drm/drm.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index c1fa1992..88055f54 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -564,7 +564,7 @@ static bool drm_connector_set_mode(struct wlr_output *output, struct wlr_drm_crtc *crtc = conn->crtc; if (!crtc) { wlr_log(WLR_ERROR, "Unable to match %s with a CRTC", conn->output.name); - goto error_conn; + return false; } wlr_log(WLR_DEBUG, "%s: crtc=%td ovr=%td pri=%td cur=%td", conn->output.name, crtc - drm->crtcs, @@ -864,11 +864,13 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { return; } - size_t seen_len = wl_list_length(&drm->outputs); + size_t drm_outputs_len = wl_list_length(&drm->outputs); // +1 so length can never be 0, which is undefined behaviour. // Last element isn't used. - bool seen[seen_len + 1]; - memset(seen, 0, sizeof(seen)); + bool seen[drm_outputs_len + 1]; + memset(seen, false, sizeof(seen)); + size_t new_outputs_len = 0; + struct wlr_drm_connector *new_outputs[drm_outputs_len + 1]; for (int i = 0; i < res->count_connectors; ++i) { drmModeConnector *drm_conn = drmModeGetConnector(drm->fd, @@ -974,13 +976,10 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { wl_list_insert(&wlr_conn->output.modes, &mode->wlr_mode.link); } - wlr_output_update_enabled(&wlr_conn->output, true); + wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL); wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; - wlr_log(WLR_INFO, "Sending modesetting signal for '%s'", - wlr_conn->output.name); - wlr_signal_emit_safe(&drm->backend.events.new_output, - &wlr_conn->output); + new_outputs[new_outputs_len++] = wlr_conn; } else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED && drm_conn->connection != DRM_MODE_CONNECTED) { wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->output.name); @@ -999,7 +998,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { size_t index = wl_list_length(&drm->outputs); wl_list_for_each_safe(conn, tmp_conn, &drm->outputs, link) { index--; - if (index >= seen_len || seen[index]) { + if (index >= drm_outputs_len || seen[index]) { continue; } @@ -1011,6 +1010,15 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { wl_list_remove(&conn->link); free(conn); } + + for (size_t i = 0; i < new_outputs_len; ++i) { + struct wlr_drm_connector *conn = new_outputs[i]; + + wlr_log(WLR_INFO, "Requesting modeset for '%s'", + conn->output.name); + wlr_signal_emit_safe(&drm->backend.events.new_output, + &conn->output); + } } static void page_flip_handler(int fd, unsigned seq, From 69a5279f7983097e13d194e30f5233898ffa6ff8 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 2 Sep 2018 14:23:22 +1000 Subject: [PATCH 09/12] xwayland: Add WM_STATE modal property Adds a modal property to indicate whether the surface wants to be a modal. --- include/wlr/xwayland.h | 1 + include/xwayland/xwm.h | 1 + xwayland/xwm.c | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 2eda768a..82ca63bc 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -138,6 +138,7 @@ struct wlr_xwayland_surface { struct wl_event_source *ping_timer; // _NET_WM_STATE + bool modal; bool fullscreen; bool maximized_vert, maximized_horz; diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index 08d37736..607cc797 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -40,6 +40,7 @@ enum atom_name { _NET_WM_MOVERESIZE, _NET_WM_NAME, _NET_SUPPORTING_WM_CHECK, + _NET_WM_STATE_MODAL, _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ, diff --git a/xwayland/xwm.c b/xwayland/xwm.c index c939d8ea..268cb6a2 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -39,6 +39,7 @@ const char *atom_map[ATOM_LAST] = { "_NET_WM_MOVERESIZE", "_NET_WM_NAME", "_NET_SUPPORTING_WM_CHECK", + "_NET_WM_STATE_MODAL", "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", @@ -268,6 +269,9 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) { int i; i = 0; + if (xsurface->modal) { + property[i++] = xwm->atoms[_NET_WM_STATE_MODAL]; + } if (xsurface->fullscreen) { property[i++] = xwm->atoms[_NET_WM_STATE_FULLSCREEN]; } @@ -575,7 +579,9 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm, xsurface->fullscreen = 0; xcb_atom_t *atom = xcb_get_property_value(reply); for (uint32_t i = 0; i < reply->value_len; i++) { - if (atom[i] == xwm->atoms[_NET_WM_STATE_FULLSCREEN]) { + if (atom[i] == xwm->atoms[_NET_WM_STATE_MODAL]) { + xsurface->modal = true; + } else if (atom[i] == xwm->atoms[_NET_WM_STATE_FULLSCREEN]) { xsurface->fullscreen = true; } else if (atom[i] == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT]) { xsurface->maximized_vert = true; @@ -1028,7 +1034,10 @@ static void xwm_handle_net_wm_state_message(struct wlr_xwm *xwm, for (size_t i = 0; i < 2; ++i) { uint32_t property = client_message->data.data32[1 + i]; - if (property == xwm->atoms[_NET_WM_STATE_FULLSCREEN] && + if (property == xwm->atoms[_NET_WM_STATE_MODAL] && + update_state(action, &xsurface->modal)) { + xsurface_set_net_wm_state(xsurface); + } else if (property == xwm->atoms[_NET_WM_STATE_FULLSCREEN] && update_state(action, &xsurface->fullscreen)) { xsurface_set_net_wm_state(xsurface); } else if (property == xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT] && @@ -1630,6 +1639,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) { xwm->atoms[NET_WM_STATE], xwm->atoms[_NET_ACTIVE_WINDOW], xwm->atoms[_NET_WM_MOVERESIZE], + xwm->atoms[_NET_WM_STATE_MODAL], xwm->atoms[_NET_WM_STATE_FULLSCREEN], xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT], xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ], From 60a174eb1165f6adc139821c863ff73d57a3ce79 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 2 Sep 2018 14:59:09 +1000 Subject: [PATCH 10/12] xwayland: Introduce request_activate event --- include/wlr/xwayland.h | 1 + xwayland/xwm.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index 82ca63bc..cf1c2cd1 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -151,6 +151,7 @@ struct wlr_xwayland_surface { struct wl_signal request_resize; struct wl_signal request_maximize; struct wl_signal request_fullscreen; + struct wl_signal request_activate; struct wl_signal map; struct wl_signal unmap; diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 268cb6a2..cebd9bbc 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -148,6 +148,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create( wl_signal_init(&surface->events.request_resize); wl_signal_init(&surface->events.request_maximize); wl_signal_init(&surface->events.request_fullscreen); + wl_signal_init(&surface->events.request_activate); wl_signal_init(&surface->events.map); wl_signal_init(&surface->events.unmap); wl_signal_init(&surface->events.set_class); @@ -1096,6 +1097,15 @@ static void xwm_handle_wm_protocols_message(struct wlr_xwm *xwm, } } +static void xwm_handle_net_active_window_message(struct wlr_xwm *xwm, + xcb_client_message_event_t *ev) { + struct wlr_xwayland_surface *surface = lookup_surface(xwm, ev->window); + if (surface == NULL) { + return; + } + wlr_signal_emit_safe(&surface->events.request_activate, surface); +} + static void xwm_handle_client_message(struct wlr_xwm *xwm, xcb_client_message_event_t *ev) { wlr_log(WLR_DEBUG, "XCB_CLIENT_MESSAGE (%u)", ev->window); @@ -1108,6 +1118,8 @@ static void xwm_handle_client_message(struct wlr_xwm *xwm, xwm_handle_net_wm_moveresize_message(xwm, ev); } else if (ev->type == xwm->atoms[WM_PROTOCOLS]) { xwm_handle_wm_protocols_message(xwm, ev); + } else if (ev->type == xwm->atoms[_NET_ACTIVE_WINDOW]) { + xwm_handle_net_active_window_message(xwm, ev); } else if (!xwm_handle_selection_client_message(xwm, ev)) { char *type_name = xwm_get_atom_name(xwm, ev->type); wlr_log(WLR_DEBUG, "unhandled x11 client message %u (%s)", ev->type, From 2f0815838d921f3fc4a22cb45985fd7d35db5d95 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 1 Sep 2018 19:27:18 +0200 Subject: [PATCH 11/12] Init dmabuf global in renderer --- include/rootston/desktop.h | 2 -- render/wlr_renderer.c | 7 ++++++- rootston/desktop.c | 4 ---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h index 363a16f0..3496fb43 100644 --- a/include/rootston/desktop.h +++ b/include/rootston/desktop.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,6 @@ struct roots_desktop { struct wlr_idle *idle; struct wlr_idle_inhibit_manager_v1 *idle_inhibit; struct wlr_input_inhibit_manager *input_inhibit; - struct wlr_linux_dmabuf_v1 *linux_dmabuf; struct wlr_layer_shell *layer_shell; struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard; struct wlr_screencopy_manager_v1 *screencopy; diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index 6c2b9fbb..31bf2b18 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -1,10 +1,11 @@ #include #include #include +#include #include #include +#include #include -#include #include #include "util/signal.h" @@ -176,6 +177,10 @@ void wlr_renderer_init_wl_display(struct wlr_renderer *r, } } + if (r->impl->texture_from_dmabuf) { + wlr_linux_dmabuf_v1_create(wl_display, r); + } + if (r->impl->init_wl_display) { r->impl->init_wl_display(r, wl_display); } diff --git a/rootston/desktop.c b/rootston/desktop.c index 658611e3..efb7581a 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -893,9 +892,6 @@ struct roots_desktop *desktop_create(struct roots_server *server, wl_signal_add(&desktop->input_inhibit->events.deactivate, &desktop->input_inhibit_deactivate); - desktop->linux_dmabuf = wlr_linux_dmabuf_v1_create(server->wl_display, - server->renderer); - desktop->virtual_keyboard = wlr_virtual_keyboard_manager_v1_create( server->wl_display); wl_signal_add(&desktop->virtual_keyboard->events.new_virtual_keyboard, From 95d05acda511e8559ab87a3d8956ee942ca1999e Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 2 Sep 2018 09:00:21 +0200 Subject: [PATCH 12/12] backend/drm: fix invalid VLA size in scan_drm_connectors I failed to see this issue with Valgrind because of the +1. --- backend/drm/drm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 88055f54..5396dcd4 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -864,13 +864,13 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { return; } - size_t drm_outputs_len = wl_list_length(&drm->outputs); + size_t seen_len = wl_list_length(&drm->outputs); // +1 so length can never be 0, which is undefined behaviour. // Last element isn't used. - bool seen[drm_outputs_len + 1]; + bool seen[seen_len + 1]; memset(seen, false, sizeof(seen)); size_t new_outputs_len = 0; - struct wlr_drm_connector *new_outputs[drm_outputs_len + 1]; + struct wlr_drm_connector *new_outputs[res->count_connectors + 1]; for (int i = 0; i < res->count_connectors; ++i) { drmModeConnector *drm_conn = drmModeGetConnector(drm->fd, @@ -998,7 +998,7 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { size_t index = wl_list_length(&drm->outputs); wl_list_for_each_safe(conn, tmp_conn, &drm->outputs, link) { index--; - if (index >= drm_outputs_len || seen[index]) { + if (index >= seen_len || seen[index]) { continue; }