aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/xwayland.h5
-rw-r--r--xwayland/xwm.c82
-rw-r--r--xwayland/xwm.h3
3 files changed, 40 insertions, 50 deletions
diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h
index e7598d4c..6198ff22 100644
--- a/include/wlr/xwayland.h
+++ b/include/wlr/xwayland.h
@@ -96,6 +96,11 @@ struct wlr_xwayland_surface {
uint32_t hints_urgency;
struct wlr_xwayland_surface_size_hints *size_hints;
+ // _NET_WM_STATE
+ bool fullscreen;
+ bool maximized_vert;
+ bool maximized_horz;
+
struct {
struct wl_signal destroy;
struct wl_signal request_configure;
diff --git a/xwayland/xwm.c b/xwayland/xwm.c
index 01d09768..b52dfcf7 100644
--- a/xwayland/xwm.c
+++ b/xwayland/xwm.c
@@ -36,6 +36,9 @@ const char *atom_map[ATOM_LAST] = {
"_NET_WM_MOVERESIZE",
"_NET_WM_NAME",
"_NET_SUPPORTING_WM_CHECK",
+ "_NET_WM_STATE_FULLSCREEN",
+ "_NET_WM_STATE_MAXIMIZED_VERT",
+ "_NET_WM_STATE_MAXIMIZED_HORZ",
};
/* General helpers */
@@ -150,6 +153,30 @@ void xwm_surface_activate(struct wlr_xwm *xwm,
xcb_flush(xwm->xcb_conn);
}
+static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
+ struct wlr_xwm *xwm = xsurface->xwm;
+ uint32_t property[3];
+ int i;
+
+ i = 0;
+ if (xsurface->fullscreen) {
+ property[i++] = xwm->atoms[_NET_WM_STATE_FULLSCREEN];
+ }
+ if (xsurface->maximized_vert) {
+ property[i++] = xwm->atoms[_NET_WM_STATE_MAXIMIZED_VERT];
+ }
+ if (xsurface->maximized_horz) {
+ property[i++] = xwm->atoms[_NET_WM_STATE_MAXIMIZED_HORZ];
+ }
+
+ xcb_change_property(xwm->xcb_conn,
+ XCB_PROP_MODE_REPLACE,
+ xsurface->window_id,
+ xwm->atoms[NET_WM_STATE],
+ XCB_ATOM_ATOM,
+ 32, // format
+ i, property);
+}
static void wlr_xwayland_surface_destroy(struct wlr_xwayland_surface *surface) {
wl_signal_emit(&surface->events.destroy, surface);
@@ -271,44 +298,6 @@ static void read_surface_parent(struct wlr_xwm *xwm,
wl_signal_emit(&surface->events.set_parent, surface);
}
-static void handle_surface_state(struct wlr_xwm *xwm,
- struct wlr_xwayland_surface *surface, xcb_atom_t *state,
- size_t state_len, enum net_wm_state_action action) {
- for (size_t i = 0; i < state_len; i++) {
- xcb_atom_t atom = state[i];
- bool found = false;
- for (size_t j = 0; j < surface->state->length; j++) {
- xcb_atom_t *cur = surface->state->items[j];
- if (atom == *cur) {
- found = true;
- if (action == NET_WM_STATE_REMOVE ||
- action == NET_WM_STATE_TOGGLE) {
- free(surface->state->items[j]);
- wlr_list_del(surface->state, j);
- }
- break;
- }
- }
-
- if (!found && (action == NET_WM_STATE_ADD ||
- action == NET_WM_STATE_TOGGLE)) {
- xcb_atom_t *atom_ptr = malloc(sizeof(xcb_atom_t));
- *atom_ptr = atom;
- wlr_list_add(surface->state, atom_ptr);
- }
- }
-
- wlr_log(L_DEBUG, "NET_WM_STATE (%zu)", state_len);
- wl_signal_emit(&surface->events.set_state, surface);
-}
-
-static void read_surface_state(struct wlr_xwm *xwm,
- struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) {
- // reply->type == XCB_ATOM_ANY
- handle_surface_state(xwm, surface, xcb_get_property_value(reply),
- reply->value_len, NET_WM_STATE_ADD);
-}
-
static void read_surface_pid(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *surface, xcb_get_property_reply_t *reply) {
if (reply->type != XCB_ATOM_CARDINAL) {
@@ -480,7 +469,7 @@ static void read_surface_property(struct wlr_xwm *xwm,
} else if (property == xwm->atoms[WM_PROTOCOLS]) {
read_surface_protocols(xwm, surface, reply);
} else if (property == xwm->atoms[NET_WM_STATE]) {
- read_surface_state(xwm, surface, reply);
+ wlr_log(L_DEBUG, "TODO: read _NET_WM_STATE property");
} else if (property == xwm->atoms[WM_HINTS]) {
read_surface_hints(xwm, surface, reply);
} else if (property == xwm->atoms[WM_NORMAL_HINTS]) {
@@ -645,6 +634,7 @@ static void handle_map_request(struct wlr_xwm *xwm,
}
xsurface_set_wm_state(xsurface, ICCCM_NORMAL_STATE);
+ xsurface_set_net_wm_state(xsurface);
xcb_map_window(xwm->xcb_conn, ev->window);
}
@@ -716,16 +706,6 @@ static void handle_surface_id_message(struct wlr_xwm *xwm,
}
}
-static void handle_net_wm_state_message(struct wlr_xwm *xwm,
- xcb_client_message_event_t *ev) {
- struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window);
- if (xsurface == NULL) {
- return;
- }
- handle_surface_state(xwm, xsurface, &ev->data.data32[1], 2,
- ev->data.data32[0]);
-}
-
static void handle_net_wm_moveresize_message(struct wlr_xwm *xwm,
xcb_client_message_event_t *ev) {
wlr_log(L_DEBUG, "TODO: handle moveresize");
@@ -738,7 +718,7 @@ static void handle_client_message(struct wlr_xwm *xwm,
if (ev->type == xwm->atoms[WL_SURFACE_ID]) {
handle_surface_id_message(xwm, ev);
} else if (ev->type == xwm->atoms[NET_WM_STATE]) {
- handle_net_wm_state_message(xwm, ev);
+ wlr_log(L_DEBUG, "TODO: handle _NET_WM_STATE client message");
} else if (ev->type == xwm->atoms[_NET_WM_MOVERESIZE]) {
handle_net_wm_moveresize_message(xwm, ev);
} else {
@@ -1075,6 +1055,8 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *wlr_xwayland) {
sizeof(supported)/sizeof(*supported),
supported);
+ xcb_flush(xwm->xcb_conn);
+
xwm_set_net_active_window(xwm, XCB_WINDOW_NONE);
xwm->compositor_surface_create.notify = handle_compositor_surface_create;
diff --git a/xwayland/xwm.h b/xwayland/xwm.h
index 05fcfa7e..4f8c20a2 100644
--- a/xwayland/xwm.h
+++ b/xwayland/xwm.h
@@ -25,6 +25,9 @@ enum atom_name {
_NET_WM_MOVERESIZE,
_NET_WM_NAME,
_NET_SUPPORTING_WM_CHECK,
+ _NET_WM_STATE_FULLSCREEN,
+ _NET_WM_STATE_MAXIMIZED_VERT,
+ _NET_WM_STATE_MAXIMIZED_HORZ,
ATOM_LAST,
};