aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/drm.c25
-rw-r--r--backend/x11/backend.c2
-rw-r--r--examples/idle.c1
-rw-r--r--examples/multi-pointer.c19
-rw-r--r--examples/output-layout.c12
-rw-r--r--examples/pointer.c10
-rw-r--r--examples/rotation.c10
-rw-r--r--examples/simple.c10
-rw-r--r--examples/tablet.c10
-rw-r--r--examples/touch.c10
-rw-r--r--include/rootston/desktop.h2
-rw-r--r--include/wlr/xwayland.h4
-rw-r--r--include/xwayland/xwm.h2
-rw-r--r--render/wlr_renderer.c7
-rw-r--r--rootston/desktop.c4
-rw-r--r--rootston/output.c24
-rw-r--r--types/tablet_v2/wlr_tablet_v2.c17
-rw-r--r--xwayland/xwm.c53
18 files changed, 168 insertions, 54 deletions
diff --git a/backend/drm/drm.c b/backend/drm/drm.c
index a666ce71..5396dcd4 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;
}
@@ -563,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,
@@ -867,7 +868,9 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) {
// +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));
+ memset(seen, false, sizeof(seen));
+ size_t new_outputs_len = 0;
+ 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,
@@ -973,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);
@@ -1010,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,
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index e0f5d6e7..0ff2925d 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -163,6 +163,8 @@ static bool backend_start(struct wlr_backend *backend) {
0,
0,
0);
+
+ free(reply);
}
}
#endif
diff --git a/examples/idle.c b/examples/idle.c
index 87a03924..3e1565ca 100644
--- a/examples/idle.c
+++ b/examples/idle.c
@@ -129,6 +129,7 @@ int main(int argc, char *argv[]) {
wl_registry_add_listener(registry, &registry_listener, NULL);
wl_display_dispatch(display);
wl_display_roundtrip(display);
+ free(registry);
if (idle_manager == NULL) {
fprintf(stderr, "display doesn't support idle protocol\n");
diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c
index 958e90f6..49670c39 100644
--- a/examples/multi-pointer.c
+++ b/examples/multi-pointer.c
@@ -239,15 +239,21 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
case WLR_INPUT_DEVICE_POINTER:;
- struct sample_cursor *cursor = calloc(1, sizeof(struct sample_cursor));
+ struct sample_cursor *cursor = calloc(1, sizeof(struct sample_cursor));
struct sample_pointer *pointer = calloc(1, sizeof(struct sample_pointer));
pointer->device = device;
- cursor->sample = sample;
+ cursor->sample = sample;
cursor->device = device;
cursor->cursor = wlr_cursor_create();
@@ -324,6 +330,11 @@ int main(int argc, char *argv[]) {
cursor_destroy(cursor);
}
+ struct sample_pointer *pointer, *tmp_pointer;
+ wl_list_for_each_safe(pointer, tmp_pointer, &state.pointers, link) {
+ free(pointer);
+ }
+
wlr_xcursor_theme_destroy(theme);
wlr_output_layout_destroy(state.layout);
}
diff --git a/examples/output-layout.c b/examples/output-layout.c
index 2bfc5923..2d1bc58b 100644
--- a/examples/output-layout.c
+++ b/examples/output-layout.c
@@ -239,8 +239,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
default:
@@ -285,6 +291,6 @@ int main(int argc, char *argv[]) {
wlr_texture_destroy(state.cat_texture);
- wlr_output_layout_destroy(state.layout);
wl_display_destroy(state.display);
+ wlr_output_layout_destroy(state.layout);
}
diff --git a/examples/pointer.c b/examples/pointer.c
index f0d9fb4b..cc58c223 100644
--- a/examples/pointer.c
+++ b/examples/pointer.c
@@ -304,8 +304,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
default:
diff --git a/examples/rotation.c b/examples/rotation.c
index add7f42f..7cf5727b 100644
--- a/examples/rotation.c
+++ b/examples/rotation.c
@@ -188,8 +188,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
default:
diff --git a/examples/simple.c b/examples/simple.c
index 1125bd2a..e1c10906 100644
--- a/examples/simple.c
+++ b/examples/simple.c
@@ -141,8 +141,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
default:
diff --git a/examples/tablet.c b/examples/tablet.c
index 4817db4d..fad30d52 100644
--- a/examples/tablet.c
+++ b/examples/tablet.c
@@ -297,8 +297,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
case WLR_INPUT_DEVICE_TABLET_PAD:;
diff --git a/examples/touch.c b/examples/touch.c
index ba5d1e34..9ed20a28 100644
--- a/examples/touch.c
+++ b/examples/touch.c
@@ -210,8 +210,14 @@ void new_input_notify(struct wl_listener *listener, void *data) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
exit(1);
}
- wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,
- &rules, XKB_KEYMAP_COMPILE_NO_FLAGS));
+ struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (!keymap) {
+ wlr_log(WLR_ERROR, "Failed to create XKB keymap");
+ exit(1);
+ }
+ wlr_keyboard_set_keymap(device->keyboard, keymap);
+ xkb_keymap_unref(keymap);
xkb_context_unref(context);
break;
case WLR_INPUT_DEVICE_TOUCH:;
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 <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_layer_shell.h>
-#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_list.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h>
@@ -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/include/wlr/xwayland.h b/include/wlr/xwayland.h
index 2eda768a..eb5d6985 100644
--- a/include/wlr/xwayland.h
+++ b/include/wlr/xwayland.h
@@ -116,6 +116,7 @@ struct wlr_xwayland_surface {
char *title;
char *class;
char *instance;
+ char *role;
pid_t pid;
bool has_utf8_title;
@@ -138,6 +139,7 @@ struct wlr_xwayland_surface {
struct wl_event_source *ping_timer;
// _NET_WM_STATE
+ bool modal;
bool fullscreen;
bool maximized_vert, maximized_horz;
@@ -150,11 +152,13 @@ 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;
struct wl_signal set_title;
struct wl_signal set_class;
+ struct wl_signal set_role;
struct wl_signal set_parent;
struct wl_signal set_pid;
struct wl_signal set_window_type;
diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h
index 08d37736..3536bbc8 100644
--- a/include/xwayland/xwm.h
+++ b/include/xwayland/xwm.h
@@ -25,6 +25,7 @@ enum atom_name {
WM_HINTS,
WM_NORMAL_HINTS,
WM_SIZE_HINTS,
+ WM_WINDOW_ROLE,
MOTIF_WM_HINTS,
UTF8_STRING,
WM_S0,
@@ -40,6 +41,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/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 <assert.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <wlr/render/gles2.h>
#include <wlr/render/interface.h>
#include <wlr/render/wlr_renderer.h>
+#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_matrix.h>
-#include <wlr/render/gles2.h>
#include <wlr/util/log.h>
#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 <wlr/types/wlr_idle.h>
#include <wlr/types/wlr_input_inhibitor.h>
#include <wlr/types/wlr_layer_shell.h>
-#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_server_decoration.h>
@@ -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,
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,
diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c
index 45036839..7f3d5f30 100644
--- a/types/tablet_v2/wlr_tablet_v2.c
+++ b/types/tablet_v2/wlr_tablet_v2.c
@@ -163,7 +163,7 @@ static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *res
struct wlr_tablet_seat_client_v2 *seat_client =
calloc(1, sizeof(struct wlr_tablet_seat_client_v2));
- if (tablet_seat == NULL) {
+ if (seat_client == NULL) {
wl_client_post_no_memory(wl_client);
return;
}
@@ -283,6 +283,7 @@ void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager) {
}
wlr_signal_emit_safe(&manager->events.destroy, manager);
+ wl_list_remove(&manager->display_destroy.link);
wl_global_destroy(manager->wl_global);
free(manager);
}
@@ -294,13 +295,6 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) {
return NULL;
}
- wl_signal_init(&tablet->events.destroy);
- wl_list_init(&tablet->clients);
- wl_list_init(&tablet->seats);
-
- tablet->display_destroy.notify = handle_display_destroy;
- wl_display_add_destroy_listener(display, &tablet->display_destroy);
-
tablet->wl_global = wl_global_create(display,
&zwp_tablet_manager_v2_interface, TABLET_MANAGER_VERSION,
tablet, tablet_v2_bind);
@@ -309,5 +303,12 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) {
return NULL;
}
+ wl_signal_init(&tablet->events.destroy);
+ wl_list_init(&tablet->clients);
+ wl_list_init(&tablet->seats);
+
+ tablet->display_destroy.notify = handle_display_destroy;
+ wl_display_add_destroy_listener(display, &tablet->display_destroy);
+
return tablet;
}
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index c939d8ea..9c803543 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -24,6 +24,7 @@ const char *atom_map[ATOM_LAST] = {
"WM_HINTS",
"WM_NORMAL_HINTS",
"WM_SIZE_HINTS",
+ "WM_WINDOW_ROLE",
"_MOTIF_WM_HINTS",
"UTF8_STRING",
"WM_S0",
@@ -39,6 +40,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",
@@ -147,9 +149,11 @@ 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);
+ wl_signal_init(&surface->events.set_role);
wl_signal_init(&surface->events.set_title);
wl_signal_init(&surface->events.set_parent);
wl_signal_init(&surface->events.set_pid);
@@ -268,6 +272,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];
}
@@ -322,6 +329,7 @@ static void xwayland_surface_destroy(
free(xsurface->title);
free(xsurface->class);
free(xsurface->instance);
+ free(xsurface->role);
free(xsurface->window_type);
free(xsurface->protocols);
free(xsurface->hints);
@@ -360,6 +368,28 @@ static void read_surface_class(struct wlr_xwm *xwm,
wlr_signal_emit_safe(&surface->events.set_class, surface);
}
+static void read_surface_role(struct wlr_xwm *xwm,
+ struct wlr_xwayland_surface *xsurface,
+ xcb_get_property_reply_t *reply) {
+ if (reply->type != XCB_ATOM_STRING &&
+ reply->type != xwm->atoms[UTF8_STRING]) {
+ return;
+ }
+
+ size_t len = xcb_get_property_value_length(reply);
+ char *role = xcb_get_property_value(reply);
+
+ free(xsurface->role);
+ if (len > 0) {
+ xsurface->role = strndup(role, len);
+ } else {
+ xsurface->role = NULL;
+ }
+
+ wlr_log(WLR_DEBUG, "XCB_ATOM_WM_WINDOW_ROLE: %s", xsurface->role);
+ wlr_signal_emit_safe(&xsurface->events.set_role, xsurface);
+}
+
static void read_surface_title(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface,
xcb_get_property_reply_t *reply) {
@@ -575,7 +605,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;
@@ -631,6 +663,8 @@ static void read_surface_property(struct wlr_xwm *xwm,
read_surface_normal_hints(xwm, xsurface, reply);
} else if (property == xwm->atoms[MOTIF_WM_HINTS]) {
read_surface_motif_hints(xwm, xsurface, reply);
+ } else if (property == xwm->atoms[WM_WINDOW_ROLE]) {
+ read_surface_role(xwm, xsurface, reply);
} else {
char *prop_name = xwm_get_atom_name(xwm, property);
wlr_log(WLR_DEBUG, "unhandled X11 property %u (%s) for window %u",
@@ -1028,7 +1062,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] &&
@@ -1087,6 +1124,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);
@@ -1099,6 +1145,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,
@@ -1630,6 +1678,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],