systray: reparent windows
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
2c0febaedc
commit
7b00a2baf0
|
@ -136,7 +136,7 @@ end
|
||||||
mystatusbar = {}
|
mystatusbar = {}
|
||||||
for s = 1, screen.count() do
|
for s = 1, screen.count() do
|
||||||
mystatusbar[s] = statusbar({ position = "top", name = "mystatusbar" .. s,
|
mystatusbar[s] = statusbar({ position = "top", name = "mystatusbar" .. s,
|
||||||
fg = beautiful.fg_normal, bg = beautiful.bg_normal })
|
fg = beautiful.fg_normal, bg = beautiful.bg_normal })
|
||||||
-- Add widgets to the statusbar - order matters
|
-- Add widgets to the statusbar - order matters
|
||||||
mystatusbar[s]:widgets({
|
mystatusbar[s]:widgets({
|
||||||
mytaglist,
|
mytaglist,
|
||||||
|
@ -145,7 +145,7 @@ for s = 1, screen.count() do
|
||||||
mypromptbox,
|
mypromptbox,
|
||||||
mytextbox,
|
mytextbox,
|
||||||
mylayoutbox[s],
|
mylayoutbox[s],
|
||||||
s == screen.count() and mysystray or nil
|
s == 1 and mysystray or nil
|
||||||
})
|
})
|
||||||
mystatusbar[s].screen = s
|
mystatusbar[s].screen = s
|
||||||
end
|
end
|
||||||
|
|
11
client.c
11
client.c
|
@ -274,7 +274,6 @@ client_stack(void)
|
||||||
layer_t layer;
|
layer_t layer;
|
||||||
statusbar_t *sb;
|
statusbar_t *sb;
|
||||||
int screen;
|
int screen;
|
||||||
xembed_window_t *emwin;
|
|
||||||
|
|
||||||
config_win_vals[0] = XCB_NONE;
|
config_win_vals[0] = XCB_NONE;
|
||||||
config_win_vals[1] = XCB_STACK_MODE_BELOW;
|
config_win_vals[1] = XCB_STACK_MODE_BELOW;
|
||||||
|
@ -300,16 +299,6 @@ client_stack(void)
|
||||||
config_win_vals[0] = node->client->win;
|
config_win_vals[0] = node->client->win;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then stack systray windows */
|
|
||||||
for(emwin = globalconf.embedded; emwin; emwin = emwin->next)
|
|
||||||
{
|
|
||||||
xcb_configure_window(globalconf.connection,
|
|
||||||
emwin->win,
|
|
||||||
XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE,
|
|
||||||
config_win_vals);
|
|
||||||
config_win_vals[0] = emwin->win;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* then stack statusbar window */
|
/* then stack statusbar window */
|
||||||
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++)
|
for(screen = 0; screen < globalconf.screens_info->nscreen; screen++)
|
||||||
for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next)
|
for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next)
|
||||||
|
|
96
statusbar.c
96
statusbar.c
|
@ -39,15 +39,13 @@ DO_LUA_EQ(statusbar_t, statusbar, "statusbar")
|
||||||
static void
|
static void
|
||||||
statusbar_systray_kickout(int phys_screen)
|
statusbar_systray_kickout(int phys_screen)
|
||||||
{
|
{
|
||||||
xembed_window_t *em;
|
xcb_screen_t *s = xutil_screen_get(globalconf.connection, phys_screen);
|
||||||
uint32_t config_win_vals_off[2] = { -512, -512 };
|
|
||||||
|
|
||||||
for(em = globalconf.embedded; em; em = em->next)
|
xcb_reparent_window(globalconf.connection,
|
||||||
if(em->phys_screen == phys_screen)
|
globalconf.screens[phys_screen].systray.window,
|
||||||
xcb_configure_window(globalconf.connection, em->win,
|
s->root, -512, -512);
|
||||||
XCB_CONFIG_WINDOW_X
|
|
||||||
| XCB_CONFIG_WINDOW_Y,
|
globalconf.screens[phys_screen].systray.parent = s->root;
|
||||||
config_win_vals_off);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -61,35 +59,77 @@ statusbar_systray_refresh(statusbar_t *statusbar)
|
||||||
for(systray = statusbar->widgets; systray; systray = systray->next)
|
for(systray = statusbar->widgets; systray; systray = systray->next)
|
||||||
if(systray->widget->type == systray_new)
|
if(systray->widget->type == systray_new)
|
||||||
{
|
{
|
||||||
uint32_t config_back[] = { globalconf.colors.bg.pixel };
|
uint32_t config_back[] = { statusbar->colors.bg.pixel };
|
||||||
uint32_t config_win_vals[4];
|
uint32_t config_win_vals[4];
|
||||||
uint32_t config_win_vals_off[2] = { -512, -512 };
|
uint32_t config_win_vals_off[2] = { -512, -512 };
|
||||||
xembed_window_t *em;
|
xembed_window_t *em;
|
||||||
position_t pos;
|
position_t pos;
|
||||||
|
|
||||||
if(statusbar->position
|
if(statusbar->position
|
||||||
&& systray->widget->isvisible)
|
&& systray->widget->isvisible
|
||||||
|
&& systray->area.width)
|
||||||
{
|
{
|
||||||
pos = statusbar->position;
|
pos = statusbar->position;
|
||||||
/* width */
|
|
||||||
config_win_vals[2] = systray->area.height;
|
/* Set background of the systray window. */
|
||||||
/* height */
|
xcb_change_window_attributes(globalconf.connection,
|
||||||
config_win_vals[3] = systray->area.height;
|
globalconf.screens[statusbar->phys_screen].systray.window,
|
||||||
|
XCB_CW_BACK_PIXEL, config_back);
|
||||||
|
/* Map it. */
|
||||||
|
xcb_map_window(globalconf.connection, globalconf.screens[statusbar->phys_screen].systray.window);
|
||||||
|
/* Move it. */
|
||||||
|
switch(statusbar->position)
|
||||||
|
{
|
||||||
|
case Left:
|
||||||
|
config_win_vals[0] = systray->area.y;
|
||||||
|
config_win_vals[1] = statusbar->sw->geometry.height - systray->area.x - systray->area.width;
|
||||||
|
config_win_vals[2] = systray->area.height;
|
||||||
|
config_win_vals[3] = systray->area.width;
|
||||||
|
break;
|
||||||
|
case Right:
|
||||||
|
config_win_vals[0] = systray->area.y;
|
||||||
|
config_win_vals[1] = systray->area.x;
|
||||||
|
config_win_vals[2] = systray->area.height;
|
||||||
|
config_win_vals[3] = systray->area.width;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
config_win_vals[0] = systray->area.x;
|
||||||
|
config_win_vals[1] = systray->area.y;
|
||||||
|
config_win_vals[2] = systray->area.width;
|
||||||
|
config_win_vals[3] = systray->area.height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* reparent */
|
||||||
|
if(globalconf.screens[statusbar->phys_screen].systray.parent != statusbar->sw->window)
|
||||||
|
{
|
||||||
|
xcb_reparent_window(globalconf.connection,
|
||||||
|
globalconf.screens[statusbar->phys_screen].systray.window,
|
||||||
|
statusbar->sw->window,
|
||||||
|
config_win_vals[0], config_win_vals[1]);
|
||||||
|
globalconf.screens[statusbar->phys_screen].systray.parent = statusbar->sw->window;
|
||||||
|
}
|
||||||
|
xcb_configure_window(globalconf.connection,
|
||||||
|
globalconf.screens[statusbar->phys_screen].systray.window,
|
||||||
|
XCB_CONFIG_WINDOW_X
|
||||||
|
| XCB_CONFIG_WINDOW_Y
|
||||||
|
| XCB_CONFIG_WINDOW_WIDTH
|
||||||
|
| XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
|
config_win_vals);
|
||||||
|
/* width = height = systray height */
|
||||||
|
config_win_vals[2] = config_win_vals[3] = systray->area.height;
|
||||||
|
config_win_vals[0] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
xcb_unmap_window(globalconf.connection, globalconf.screens[statusbar->phys_screen].systray.window);
|
||||||
/* hide */
|
/* hide */
|
||||||
pos = Off;
|
pos = Off;
|
||||||
|
}
|
||||||
for(em = globalconf.embedded; em; em = em->next)
|
|
||||||
if(em->phys_screen == statusbar->phys_screen)
|
|
||||||
xcb_change_window_attributes(globalconf.connection, em->win, XCB_CW_BACK_PIXEL, config_back);
|
|
||||||
|
|
||||||
switch(pos)
|
switch(pos)
|
||||||
{
|
{
|
||||||
case Left:
|
case Left:
|
||||||
config_win_vals[0] = statusbar->sw->geometry.x + systray->area.y;
|
config_win_vals[1] = systray->area.width - config_win_vals[3];
|
||||||
config_win_vals[1] = statusbar->sw->geometry.y + statusbar->sw->geometry.height
|
|
||||||
- systray->area.x - config_win_vals[3];
|
|
||||||
for(em = globalconf.embedded; em; em = em->next)
|
for(em = globalconf.embedded; em; em = em->next)
|
||||||
if(em->phys_screen == statusbar->phys_screen)
|
if(em->phys_screen == statusbar->phys_screen)
|
||||||
{
|
{
|
||||||
|
@ -110,11 +150,9 @@ statusbar_systray_refresh(statusbar_t *statusbar)
|
||||||
| XCB_CONFIG_WINDOW_Y,
|
| XCB_CONFIG_WINDOW_Y,
|
||||||
config_win_vals_off);
|
config_win_vals_off);
|
||||||
}
|
}
|
||||||
client_stack();
|
|
||||||
break;
|
break;
|
||||||
case Right:
|
case Right:
|
||||||
config_win_vals[0] = statusbar->sw->geometry.x - systray->area.y;
|
config_win_vals[1] = 0;
|
||||||
config_win_vals[1] = statusbar->sw->geometry.y + systray->area.x;
|
|
||||||
for(em = globalconf.embedded; em; em = em->next)
|
for(em = globalconf.embedded; em; em = em->next)
|
||||||
if(em->phys_screen == statusbar->phys_screen)
|
if(em->phys_screen == statusbar->phys_screen)
|
||||||
{
|
{
|
||||||
|
@ -135,12 +173,10 @@ statusbar_systray_refresh(statusbar_t *statusbar)
|
||||||
| XCB_CONFIG_WINDOW_Y,
|
| XCB_CONFIG_WINDOW_Y,
|
||||||
config_win_vals_off);
|
config_win_vals_off);
|
||||||
}
|
}
|
||||||
client_stack();
|
|
||||||
break;
|
break;
|
||||||
case Top:
|
case Top:
|
||||||
case Bottom:
|
case Bottom:
|
||||||
config_win_vals[0] = statusbar->sw->geometry.x + systray->area.x;
|
config_win_vals[1] = 0;
|
||||||
config_win_vals[1] = statusbar->sw->geometry.y + systray->area.y;
|
|
||||||
for(em = globalconf.embedded; em; em = em->next)
|
for(em = globalconf.embedded; em; em = em->next)
|
||||||
if(em->phys_screen == statusbar->phys_screen)
|
if(em->phys_screen == statusbar->phys_screen)
|
||||||
{
|
{
|
||||||
|
@ -162,7 +198,6 @@ statusbar_systray_refresh(statusbar_t *statusbar)
|
||||||
| XCB_CONFIG_WINDOW_Y,
|
| XCB_CONFIG_WINDOW_Y,
|
||||||
config_win_vals_off);
|
config_win_vals_off);
|
||||||
}
|
}
|
||||||
client_stack();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
statusbar_systray_kickout(statusbar->phys_screen);
|
statusbar_systray_kickout(statusbar->phys_screen);
|
||||||
|
@ -222,6 +257,11 @@ statusbar_position_update(statusbar_t *statusbar)
|
||||||
|
|
||||||
globalconf.screens[statusbar->screen].need_arrange = true;
|
globalconf.screens[statusbar->screen].need_arrange = true;
|
||||||
|
|
||||||
|
/* Who! Check that we're not deleting a statusbar with a systray, because it
|
||||||
|
* may be its parent. If so, we reparent to root before, otherwise it will
|
||||||
|
* hurt very much. */
|
||||||
|
statusbar_systray_kickout(statusbar->phys_screen);
|
||||||
|
|
||||||
simplewindow_delete(&statusbar->sw);
|
simplewindow_delete(&statusbar->sw);
|
||||||
draw_context_delete(&statusbar->ctx);
|
draw_context_delete(&statusbar->ctx);
|
||||||
|
|
||||||
|
|
|
@ -384,6 +384,8 @@ typedef struct
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
xcb_window_t window;
|
xcb_window_t window;
|
||||||
|
/** Systray window parent */
|
||||||
|
xcb_window_t parent;
|
||||||
} systray;
|
} systray;
|
||||||
/** Focused client */
|
/** Focused client */
|
||||||
client_t *client_focus;
|
client_t *client_focus;
|
||||||
|
|
|
@ -111,6 +111,10 @@ systray_request_handle(xcb_window_t embed_win, int phys_screen, xembed_info_t *i
|
||||||
select_input_val);
|
select_input_val);
|
||||||
window_state_set(embed_win, XCB_WM_WITHDRAWN_STATE);
|
window_state_set(embed_win, XCB_WM_WITHDRAWN_STATE);
|
||||||
|
|
||||||
|
xcb_reparent_window(globalconf.connection, embed_win,
|
||||||
|
globalconf.screens[phys_screen].systray.window,
|
||||||
|
0, 0);
|
||||||
|
|
||||||
em = p_new(xembed_window_t, 1);
|
em = p_new(xembed_window_t, 1);
|
||||||
em->win = embed_win;
|
em->win = embed_win;
|
||||||
em->phys_screen = phys_screen;
|
em->phys_screen = phys_screen;
|
||||||
|
|
Loading…
Reference in New Issue