Turn this into a reparenting WM
Each window is now reparented under a window created by awesome. This window is NOT visible, this commit should not cause any visible differences. Instead, this is done to work around problems with X11. The only alternative would be to ban windows by moving them offscreen which is ugly in itself and breaks pagers. Doing it like this seems to be the better solution. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
5d0a81c8bf
commit
102063dbbd
6
event.c
6
event.c
|
@ -737,8 +737,8 @@ event_handle_mappingnotify(xcb_mapping_notify_event_t *ev)
|
|||
foreach(_c, globalconf.clients)
|
||||
{
|
||||
client_t *c = *_c;
|
||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->window, XCB_BUTTON_MASK_ANY);
|
||||
xwindow_grabkeys(c->window, &c->keys);
|
||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->frame_window, XCB_BUTTON_MASK_ANY);
|
||||
xwindow_grabkeys(c->frame_window, &c->keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -747,6 +747,8 @@ static void
|
|||
event_handle_reparentnotify(xcb_reparent_notify_event_t *ev)
|
||||
{
|
||||
client_t *c;
|
||||
#warning ugly, gotta do this properly
|
||||
return 0;
|
||||
|
||||
if((c = client_getbywin(ev->window)))
|
||||
client_unmanage(c);
|
||||
|
|
|
@ -227,7 +227,7 @@ client_t *
|
|||
client_getbywin(xcb_window_t w)
|
||||
{
|
||||
foreach(c, globalconf.clients)
|
||||
if((*c)->window == w)
|
||||
if((*c)->window == w || (*c)->frame_window == w)
|
||||
return *c;
|
||||
|
||||
return NULL;
|
||||
|
@ -313,7 +313,7 @@ client_ban(client_t *c)
|
|||
{
|
||||
if(!c->isbanned)
|
||||
{
|
||||
xcb_unmap_window(globalconf.connection, c->window);
|
||||
xcb_unmap_window(globalconf.connection, c->frame_window);
|
||||
|
||||
c->isbanned = true;
|
||||
|
||||
|
@ -328,20 +328,32 @@ void
|
|||
client_ignore_enterleave_events(void)
|
||||
{
|
||||
foreach(c, globalconf.clients)
|
||||
{
|
||||
xcb_change_window_attributes(globalconf.connection,
|
||||
(*c)->window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
|
||||
xcb_change_window_attributes(globalconf.connection,
|
||||
(*c)->frame_window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []) { FRAME_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
client_restore_enterleave_events(void)
|
||||
{
|
||||
foreach(c, globalconf.clients)
|
||||
{
|
||||
xcb_change_window_attributes(globalconf.connection,
|
||||
(*c)->window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK });
|
||||
xcb_change_window_attributes(globalconf.connection,
|
||||
(*c)->frame_window,
|
||||
XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []) { FRAME_SELECT_INPUT_EVENT_MASK });
|
||||
}
|
||||
}
|
||||
|
||||
/** Record that a client got focus.
|
||||
|
@ -439,6 +451,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen,
|
|||
(uint32_t[]) { XCB_STACK_MODE_BELOW});
|
||||
|
||||
client_t *c = client_new(globalconf.L);
|
||||
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
|
||||
|
||||
/* This cannot change, ever. */
|
||||
c->phys_screen = phys_screen;
|
||||
|
@ -446,6 +459,23 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen,
|
|||
c->isbanned = true;
|
||||
/* Store window */
|
||||
c->window = w;
|
||||
c->frame_window = xcb_generate_id(globalconf.connection);
|
||||
xcb_create_window(globalconf.connection, s->root_depth, c->frame_window, s->root,
|
||||
wgeom->x, wgeom->y, wgeom->width, wgeom->height,
|
||||
wgeom->border_width, XCB_COPY_FROM_PARENT, s->root_visual,
|
||||
XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY
|
||||
| XCB_CW_WIN_GRAVITY | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
|
||||
(const uint32_t [])
|
||||
{
|
||||
globalconf.colors.bg.pixel,
|
||||
globalconf.colors.bg.pixel,
|
||||
XCB_GRAVITY_NORTH_WEST,
|
||||
XCB_GRAVITY_NORTH_WEST,
|
||||
1,
|
||||
FRAME_SELECT_INPUT_EVENT_MASK
|
||||
});
|
||||
xcb_reparent_window(globalconf.connection, w, c->frame_window, 0, 0);
|
||||
xcb_map_window(globalconf.connection, w);
|
||||
luaA_object_emit_signal(globalconf.L, -1, "property::window", 0);
|
||||
|
||||
/* Duplicate client and push it in client list */
|
||||
|
@ -693,9 +723,11 @@ client_resize(client_t *c, area_t geometry, bool hints)
|
|||
client_ignore_enterleave_events();
|
||||
|
||||
xcb_configure_window(globalconf.connection, c->window,
|
||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
|
||||
| XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
(uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height });
|
||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
(uint32_t[]) { geometry.width, geometry.height });
|
||||
xcb_configure_window(globalconf.connection, c->frame_window,
|
||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
(uint32_t[]) { geometry.x, geometry.y, geometry.width, geometry.height });
|
||||
|
||||
client_restore_enterleave_events();
|
||||
|
||||
|
@ -934,7 +966,7 @@ client_unban(client_t *c)
|
|||
{
|
||||
if(c->isbanned)
|
||||
{
|
||||
xcb_map_window(globalconf.connection, c->window);
|
||||
xcb_map_window(globalconf.connection, c->frame_window);
|
||||
|
||||
c->isbanned = false;
|
||||
}
|
||||
|
@ -989,6 +1021,8 @@ client_unmanage(client_t *c)
|
|||
* after a restart anymore. */
|
||||
xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, c->window);
|
||||
|
||||
xcb_destroy_window(globalconf.connection, c->frame_window);
|
||||
|
||||
/* set client as invalid */
|
||||
c->invalid = true;
|
||||
|
||||
|
@ -1651,8 +1685,8 @@ luaA_client_keys(lua_State *L)
|
|||
{
|
||||
luaA_key_array_set(L, 1, 2, keys);
|
||||
luaA_object_emit_signal(L, 1, "property::keys", 0);
|
||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->window, XCB_BUTTON_MASK_ANY);
|
||||
xwindow_grabkeys(c->window, keys);
|
||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->frame_window, XCB_BUTTON_MASK_ANY);
|
||||
xwindow_grabkeys(c->frame_window, keys);
|
||||
}
|
||||
|
||||
return luaA_key_array_get(L, 1, keys);
|
||||
|
|
|
@ -31,10 +31,13 @@
|
|||
|
||||
#define CLIENT_SELECT_INPUT_EVENT_MASK (XCB_EVENT_MASK_STRUCTURE_NOTIFY \
|
||||
| XCB_EVENT_MASK_PROPERTY_CHANGE \
|
||||
| XCB_EVENT_MASK_ENTER_WINDOW \
|
||||
| XCB_EVENT_MASK_LEAVE_WINDOW \
|
||||
| XCB_EVENT_MASK_FOCUS_CHANGE)
|
||||
|
||||
#define FRAME_SELECT_INPUT_EVENT_MASK (XCB_EVENT_MASK_STRUCTURE_NOTIFY \
|
||||
| XCB_EVENT_MASK_ENTER_WINDOW \
|
||||
| XCB_EVENT_MASK_LEAVE_WINDOW \
|
||||
| XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT)
|
||||
|
||||
/** Windows type */
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
@ -28,6 +28,14 @@
|
|||
|
||||
LUA_CLASS_FUNCS(window, window_class)
|
||||
|
||||
static xcb_window_t
|
||||
window_get(window_t *window)
|
||||
{
|
||||
if (window->frame_window != XCB_NONE)
|
||||
return window->frame_window;
|
||||
return window->window;
|
||||
}
|
||||
|
||||
static void
|
||||
window_wipe(window_t *window)
|
||||
{
|
||||
|
@ -47,7 +55,7 @@ luaA_window_buttons(lua_State *L)
|
|||
{
|
||||
luaA_button_array_set(L, 1, 2, &window->buttons);
|
||||
luaA_object_emit_signal(L, 1, "property::buttons", 0);
|
||||
xwindow_buttons_grab(window->window, &window->buttons);
|
||||
xwindow_buttons_grab(window_get(window), &window->buttons);
|
||||
}
|
||||
|
||||
return luaA_button_array_get(L, 1, &window->buttons);
|
||||
|
@ -87,7 +95,7 @@ window_set_opacity(lua_State *L, int idx, double opacity)
|
|||
if(window->opacity != opacity)
|
||||
{
|
||||
window->opacity = opacity;
|
||||
xwindow_set_opacity(window->window, opacity);
|
||||
xwindow_set_opacity(window_get(window), opacity);
|
||||
luaA_object_emit_signal(L, idx, "property::opacity", 0);
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +149,7 @@ luaA_window_set_border_color(lua_State *L, window_t *window)
|
|||
if(color_name &&
|
||||
xcolor_init_reply(xcolor_init_unchecked(&window->border_color, color_name, len)))
|
||||
{
|
||||
xwindow_set_border_color(window->window, &window->border_color);
|
||||
xwindow_set_border_color(window_get(window), &window->border_color);
|
||||
luaA_object_emit_signal(L, -3, "property::border_color", 0);
|
||||
}
|
||||
|
||||
|
@ -162,7 +170,7 @@ window_set_border_width(lua_State *L, int idx, int width)
|
|||
return;
|
||||
|
||||
if(window->window)
|
||||
xcb_configure_window(globalconf.connection, window->window,
|
||||
xcb_configure_window(globalconf.connection, window_get(window),
|
||||
XCB_CONFIG_WINDOW_BORDER_WIDTH,
|
||||
(uint32_t[]) { width });
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
LUA_OBJECT_HEADER \
|
||||
/** The X window number */ \
|
||||
xcb_window_t window; \
|
||||
/** The frame window, might be XCB_NONE */ \
|
||||
xcb_window_t frame_window; \
|
||||
/** Opacity */ \
|
||||
double opacity; \
|
||||
/** Strut */ \
|
||||
|
|
4
stack.c
4
stack.c
|
@ -96,9 +96,9 @@ stack_window_above(xcb_window_t w, xcb_window_t previous)
|
|||
static xcb_window_t
|
||||
stack_client_above(client_t *c, xcb_window_t previous)
|
||||
{
|
||||
stack_window_above(c->window, previous);
|
||||
stack_window_above(c->frame_window, previous);
|
||||
|
||||
previous = c->window;
|
||||
previous = c->frame_window;
|
||||
|
||||
/* stack transient window on top of their parents */
|
||||
foreach(node, globalconf.stack)
|
||||
|
|
Loading…
Reference in New Issue