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)
|
foreach(_c, globalconf.clients)
|
||||||
{
|
{
|
||||||
client_t *c = *_c;
|
client_t *c = *_c;
|
||||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->window, XCB_BUTTON_MASK_ANY);
|
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->frame_window, XCB_BUTTON_MASK_ANY);
|
||||||
xwindow_grabkeys(c->window, &c->keys);
|
xwindow_grabkeys(c->frame_window, &c->keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -747,6 +747,8 @@ static void
|
||||||
event_handle_reparentnotify(xcb_reparent_notify_event_t *ev)
|
event_handle_reparentnotify(xcb_reparent_notify_event_t *ev)
|
||||||
{
|
{
|
||||||
client_t *c;
|
client_t *c;
|
||||||
|
#warning ugly, gotta do this properly
|
||||||
|
return 0;
|
||||||
|
|
||||||
if((c = client_getbywin(ev->window)))
|
if((c = client_getbywin(ev->window)))
|
||||||
client_unmanage(c);
|
client_unmanage(c);
|
||||||
|
|
|
@ -227,7 +227,7 @@ client_t *
|
||||||
client_getbywin(xcb_window_t w)
|
client_getbywin(xcb_window_t w)
|
||||||
{
|
{
|
||||||
foreach(c, globalconf.clients)
|
foreach(c, globalconf.clients)
|
||||||
if((*c)->window == w)
|
if((*c)->window == w || (*c)->frame_window == w)
|
||||||
return *c;
|
return *c;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -313,7 +313,7 @@ client_ban(client_t *c)
|
||||||
{
|
{
|
||||||
if(!c->isbanned)
|
if(!c->isbanned)
|
||||||
{
|
{
|
||||||
xcb_unmap_window(globalconf.connection, c->window);
|
xcb_unmap_window(globalconf.connection, c->frame_window);
|
||||||
|
|
||||||
c->isbanned = true;
|
c->isbanned = true;
|
||||||
|
|
||||||
|
@ -328,20 +328,32 @@ void
|
||||||
client_ignore_enterleave_events(void)
|
client_ignore_enterleave_events(void)
|
||||||
{
|
{
|
||||||
foreach(c, globalconf.clients)
|
foreach(c, globalconf.clients)
|
||||||
|
{
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
xcb_change_window_attributes(globalconf.connection,
|
||||||
(*c)->window,
|
(*c)->window,
|
||||||
XCB_CW_EVENT_MASK,
|
XCB_CW_EVENT_MASK,
|
||||||
(const uint32_t []) { CLIENT_SELECT_INPUT_EVENT_MASK & ~(XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW) });
|
(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
|
void
|
||||||
client_restore_enterleave_events(void)
|
client_restore_enterleave_events(void)
|
||||||
{
|
{
|
||||||
foreach(c, globalconf.clients)
|
foreach(c, globalconf.clients)
|
||||||
|
{
|
||||||
xcb_change_window_attributes(globalconf.connection,
|
xcb_change_window_attributes(globalconf.connection,
|
||||||
(*c)->window,
|
(*c)->window,
|
||||||
XCB_CW_EVENT_MASK,
|
XCB_CW_EVENT_MASK,
|
||||||
(const uint32_t []) { CLIENT_SELECT_INPUT_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.
|
/** 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});
|
(uint32_t[]) { XCB_STACK_MODE_BELOW});
|
||||||
|
|
||||||
client_t *c = client_new(globalconf.L);
|
client_t *c = client_new(globalconf.L);
|
||||||
|
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
|
||||||
|
|
||||||
/* This cannot change, ever. */
|
/* This cannot change, ever. */
|
||||||
c->phys_screen = phys_screen;
|
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;
|
c->isbanned = true;
|
||||||
/* Store window */
|
/* Store window */
|
||||||
c->window = w;
|
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);
|
luaA_object_emit_signal(globalconf.L, -1, "property::window", 0);
|
||||||
|
|
||||||
/* Duplicate client and push it in client list */
|
/* 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();
|
client_ignore_enterleave_events();
|
||||||
|
|
||||||
xcb_configure_window(globalconf.connection, c->window,
|
xcb_configure_window(globalconf.connection, c->window,
|
||||||
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
|
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
| XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
(uint32_t[]) { geometry.width, geometry.height });
|
||||||
(uint32_t[]) { geometry.x, geometry.y, 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();
|
client_restore_enterleave_events();
|
||||||
|
|
||||||
|
@ -934,7 +966,7 @@ client_unban(client_t *c)
|
||||||
{
|
{
|
||||||
if(c->isbanned)
|
if(c->isbanned)
|
||||||
{
|
{
|
||||||
xcb_map_window(globalconf.connection, c->window);
|
xcb_map_window(globalconf.connection, c->frame_window);
|
||||||
|
|
||||||
c->isbanned = false;
|
c->isbanned = false;
|
||||||
}
|
}
|
||||||
|
@ -989,6 +1021,8 @@ client_unmanage(client_t *c)
|
||||||
* after a restart anymore. */
|
* after a restart anymore. */
|
||||||
xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, c->window);
|
xcb_change_save_set(globalconf.connection, XCB_SET_MODE_DELETE, c->window);
|
||||||
|
|
||||||
|
xcb_destroy_window(globalconf.connection, c->frame_window);
|
||||||
|
|
||||||
/* set client as invalid */
|
/* set client as invalid */
|
||||||
c->invalid = true;
|
c->invalid = true;
|
||||||
|
|
||||||
|
@ -1651,8 +1685,8 @@ luaA_client_keys(lua_State *L)
|
||||||
{
|
{
|
||||||
luaA_key_array_set(L, 1, 2, keys);
|
luaA_key_array_set(L, 1, 2, keys);
|
||||||
luaA_object_emit_signal(L, 1, "property::keys", 0);
|
luaA_object_emit_signal(L, 1, "property::keys", 0);
|
||||||
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->window, XCB_BUTTON_MASK_ANY);
|
xcb_ungrab_key(globalconf.connection, XCB_GRAB_ANY, c->frame_window, XCB_BUTTON_MASK_ANY);
|
||||||
xwindow_grabkeys(c->window, keys);
|
xwindow_grabkeys(c->frame_window, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
return luaA_key_array_get(L, 1, keys);
|
return luaA_key_array_get(L, 1, keys);
|
||||||
|
|
|
@ -31,10 +31,13 @@
|
||||||
|
|
||||||
#define CLIENT_SELECT_INPUT_EVENT_MASK (XCB_EVENT_MASK_STRUCTURE_NOTIFY \
|
#define CLIENT_SELECT_INPUT_EVENT_MASK (XCB_EVENT_MASK_STRUCTURE_NOTIFY \
|
||||||
| XCB_EVENT_MASK_PROPERTY_CHANGE \
|
| XCB_EVENT_MASK_PROPERTY_CHANGE \
|
||||||
| XCB_EVENT_MASK_ENTER_WINDOW \
|
|
||||||
| XCB_EVENT_MASK_LEAVE_WINDOW \
|
|
||||||
| XCB_EVENT_MASK_FOCUS_CHANGE)
|
| 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 */
|
/** Windows type */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,6 +28,14 @@
|
||||||
|
|
||||||
LUA_CLASS_FUNCS(window, window_class)
|
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
|
static void
|
||||||
window_wipe(window_t *window)
|
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_button_array_set(L, 1, 2, &window->buttons);
|
||||||
luaA_object_emit_signal(L, 1, "property::buttons", 0);
|
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);
|
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)
|
if(window->opacity != opacity)
|
||||||
{
|
{
|
||||||
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);
|
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 &&
|
if(color_name &&
|
||||||
xcolor_init_reply(xcolor_init_unchecked(&window->border_color, color_name, len)))
|
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);
|
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;
|
return;
|
||||||
|
|
||||||
if(window->window)
|
if(window->window)
|
||||||
xcb_configure_window(globalconf.connection, window->window,
|
xcb_configure_window(globalconf.connection, window_get(window),
|
||||||
XCB_CONFIG_WINDOW_BORDER_WIDTH,
|
XCB_CONFIG_WINDOW_BORDER_WIDTH,
|
||||||
(uint32_t[]) { width });
|
(uint32_t[]) { width });
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
LUA_OBJECT_HEADER \
|
LUA_OBJECT_HEADER \
|
||||||
/** The X window number */ \
|
/** The X window number */ \
|
||||||
xcb_window_t window; \
|
xcb_window_t window; \
|
||||||
|
/** The frame window, might be XCB_NONE */ \
|
||||||
|
xcb_window_t frame_window; \
|
||||||
/** Opacity */ \
|
/** Opacity */ \
|
||||||
double opacity; \
|
double opacity; \
|
||||||
/** Strut */ \
|
/** 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
|
static xcb_window_t
|
||||||
stack_client_above(client_t *c, xcb_window_t previous)
|
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 */
|
/* stack transient window on top of their parents */
|
||||||
foreach(node, globalconf.stack)
|
foreach(node, globalconf.stack)
|
||||||
|
|
Loading…
Reference in New Issue