mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-22 18:09:49 +01:00
xwm: Set _NET_WM_STATE_FOCUSED property for the focused surface
Certain clients require this property to be set for expected behavior. Most notably, steam client CSD maximize button no longer worked after unmaximizing once, unless the state was changed by another method. The state is unset whenever another surface gains focus.
This commit is contained in:
parent
1ae2d976c0
commit
6d0ee53e1a
2 changed files with 26 additions and 8 deletions
|
@ -40,6 +40,7 @@ enum atom_name {
|
|||
NET_ACTIVE_WINDOW,
|
||||
NET_WM_MOVERESIZE,
|
||||
NET_SUPPORTING_WM_CHECK,
|
||||
NET_WM_STATE_FOCUSED,
|
||||
NET_WM_STATE_MODAL,
|
||||
NET_WM_STATE_FULLSCREEN,
|
||||
NET_WM_STATE_MAXIMIZED_VERT,
|
||||
|
|
|
@ -38,6 +38,7 @@ const char *atom_map[ATOM_LAST] = {
|
|||
[NET_ACTIVE_WINDOW] = "_NET_ACTIVE_WINDOW",
|
||||
[NET_WM_MOVERESIZE] = "_NET_WM_MOVERESIZE",
|
||||
[NET_SUPPORTING_WM_CHECK] = "_NET_SUPPORTING_WM_CHECK",
|
||||
[NET_WM_STATE_FOCUSED] = "_NET_WM_STATE_FOCUSED",
|
||||
[NET_WM_STATE_MODAL] = "_NET_WM_STATE_MODAL",
|
||||
[NET_WM_STATE_FULLSCREEN] = "_NET_WM_STATE_FULLSCREEN",
|
||||
[NET_WM_STATE_MAXIMIZED_VERT] = "_NET_WM_STATE_MAXIMIZED_VERT",
|
||||
|
@ -238,8 +239,20 @@ static void xwm_set_net_client_list(struct wlr_xwm *xwm) {
|
|||
XCB_ATOM_WINDOW, 32, mapped_surfaces, windows);
|
||||
}
|
||||
|
||||
static void xwm_send_focus_window(struct wlr_xwm *xwm,
|
||||
static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface);
|
||||
|
||||
static void xwm_set_focus_window(struct wlr_xwm *xwm,
|
||||
struct wlr_xwayland_surface *xsurface) {
|
||||
struct wlr_xwayland_surface *unfocus_surface = xwm->focus_surface;
|
||||
|
||||
// We handle cases where focus_surface == xsurface because we
|
||||
// want to be able to deny FocusIn events.
|
||||
xwm->focus_surface = xsurface;
|
||||
|
||||
if (unfocus_surface) {
|
||||
xsurface_set_net_wm_state(unfocus_surface);
|
||||
}
|
||||
|
||||
if (!xsurface) {
|
||||
xcb_set_input_focus_checked(xwm->xcb_conn,
|
||||
XCB_INPUT_FOCUS_POINTER_ROOT,
|
||||
|
@ -270,6 +283,8 @@ static void xwm_send_focus_window(struct wlr_xwm *xwm,
|
|||
values[0] = XCB_STACK_MODE_ABOVE;
|
||||
xcb_configure_window(xwm->xcb_conn, xsurface->window_id,
|
||||
XCB_CONFIG_WINDOW_STACK_MODE, values);
|
||||
|
||||
xsurface_set_net_wm_state(xsurface);
|
||||
}
|
||||
|
||||
static void xwm_surface_activate(struct wlr_xwm *xwm,
|
||||
|
@ -285,9 +300,7 @@ static void xwm_surface_activate(struct wlr_xwm *xwm,
|
|||
xwm_set_net_active_window(xwm, XCB_WINDOW_NONE);
|
||||
}
|
||||
|
||||
xwm_send_focus_window(xwm, xsurface);
|
||||
|
||||
xwm->focus_surface = xsurface;
|
||||
xwm_set_focus_window(xwm, xsurface);
|
||||
|
||||
xcb_flush(xwm->xcb_conn);
|
||||
}
|
||||
|
@ -295,7 +308,7 @@ static void xwm_surface_activate(struct wlr_xwm *xwm,
|
|||
static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
|
||||
struct wlr_xwm *xwm = xsurface->xwm;
|
||||
|
||||
uint32_t property[5];
|
||||
uint32_t property[6];
|
||||
size_t i = 0;
|
||||
if (xsurface->modal) {
|
||||
property[i++] = xwm->atoms[NET_WM_STATE_MODAL];
|
||||
|
@ -312,6 +325,9 @@ static void xsurface_set_net_wm_state(struct wlr_xwayland_surface *xsurface) {
|
|||
if (xsurface->minimized) {
|
||||
property[i++] = xwm->atoms[NET_WM_STATE_HIDDEN];
|
||||
}
|
||||
if (xsurface == xwm->focus_surface) {
|
||||
property[i++] = xwm->atoms[NET_WM_STATE_FOCUSED];
|
||||
}
|
||||
assert(i <= sizeof(property) / sizeof(property[0]));
|
||||
|
||||
xcb_change_property(xwm->xcb_conn,
|
||||
|
@ -1299,10 +1315,10 @@ static void xwm_handle_focus_in(struct wlr_xwm *xwm,
|
|||
struct wlr_xwayland_surface *requested_focus = lookup_surface(xwm, ev->event);
|
||||
if (xwm->focus_surface && requested_focus &&
|
||||
requested_focus->pid == xwm->focus_surface->pid) {
|
||||
xwm->focus_surface = requested_focus;
|
||||
xwm_set_focus_window(xwm, requested_focus);
|
||||
} else {
|
||||
xwm_set_focus_window(xwm, xwm->focus_surface);
|
||||
}
|
||||
|
||||
xwm_send_focus_window(xwm, xwm->focus_surface);
|
||||
}
|
||||
|
||||
static void xwm_handle_xcb_error(struct wlr_xwm *xwm, xcb_value_error_t *ev) {
|
||||
|
@ -1817,6 +1833,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
|||
xwm->atoms[NET_WM_STATE],
|
||||
xwm->atoms[NET_ACTIVE_WINDOW],
|
||||
xwm->atoms[NET_WM_MOVERESIZE],
|
||||
xwm->atoms[NET_WM_STATE_FOCUSED],
|
||||
xwm->atoms[NET_WM_STATE_MODAL],
|
||||
xwm->atoms[NET_WM_STATE_FULLSCREEN],
|
||||
xwm->atoms[NET_WM_STATE_MAXIMIZED_VERT],
|
||||
|
|
Loading…
Reference in a new issue