make helper windows share desktops with all their application top level windows

This commit is contained in:
Dana Jansens 2007-05-08 01:25:30 +00:00
parent 5945d2e9c8
commit ebabf3943c
5 changed files with 77 additions and 28 deletions

View file

@ -1351,7 +1351,7 @@ void action_toggle_omnipresent(union ActionData *data)
{
client_set_desktop(data->client.any.c,
data->client.any.c->desktop == DESKTOP_ALL ?
screen_desktop : DESKTOP_ALL, FALSE);
screen_desktop : DESKTOP_ALL, FALSE, FALSE);
}
void action_move_relative_horz(union ActionData *data)
@ -1515,7 +1515,7 @@ void action_send_to_desktop(union ActionData *data)
if (data->sendto.desk < screen_num_desktops ||
data->sendto.desk == DESKTOP_ALL) {
client_set_desktop(c, data->sendto.desk, data->sendto.follow);
client_set_desktop(c, data->sendto.desk, data->sendto.follow, FALSE);
if (data->sendto.follow)
screen_set_desktop(data->sendto.desk, TRUE);
}
@ -1582,7 +1582,7 @@ void action_send_to_desktop_dir(union ActionData *data)
!data->sendtodir.inter.final ||
data->sendtodir.inter.cancel)
{
client_set_desktop(c, d, data->sendtodir.follow);
client_set_desktop(c, d, data->sendtodir.follow, FALSE);
if (data->sendtodir.follow)
screen_set_desktop(d, TRUE);
}

View file

@ -2812,7 +2812,7 @@ static void client_iconify_recursive(ObClient *self,
if (curdesk && self->desktop != screen_desktop &&
self->desktop != DESKTOP_ALL)
client_set_desktop(self, screen_desktop, FALSE);
client_set_desktop(self, screen_desktop, FALSE, FALSE);
/* this puts it after the current focused window */
focus_order_remove(self);
@ -2992,7 +2992,9 @@ void client_hilite(ObClient *self, gboolean hilite)
}
void client_set_desktop_recursive(ObClient *self,
guint target, gboolean donthide)
guint target,
gboolean donthide,
gboolean focus_nonintrusive)
{
guint old;
GSList *it;
@ -3004,7 +3006,8 @@ void client_set_desktop_recursive(ObClient *self,
g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
/* remove from the old desktop(s) */
focus_order_remove(self);
if (!focus_nonintrusive)
focus_order_remove(self);
old = self->desktop;
self->desktop = target;
@ -3021,10 +3024,12 @@ void client_set_desktop_recursive(ObClient *self,
screen_update_areas();
/* add to the new desktop(s) */
if (config_focus_new)
focus_order_to_top(self);
else
focus_order_to_bottom(self);
if (!focus_nonintrusive) {
if (config_focus_new)
focus_order_to_top(self);
else
focus_order_to_bottom(self);
}
/* call the notifies */
GSList *it;
@ -3038,13 +3043,15 @@ void client_set_desktop_recursive(ObClient *self,
for (it = self->transients; it; it = g_slist_next(it))
if (it->data != self)
if (client_is_direct_child(self, it->data))
client_set_desktop_recursive(it->data, target, donthide);
client_set_desktop_recursive(it->data, target,
donthide, focus_nonintrusive);
}
void client_set_desktop(ObClient *self, guint target, gboolean donthide)
void client_set_desktop(ObClient *self, guint target,
gboolean donthide, gboolean focus_nonintrusive)
{
self = client_search_top_normal_parent(self);
client_set_desktop_recursive(self, target, donthide);
client_set_desktop_recursive(self, target, donthide, focus_nonintrusive);
}
gboolean client_is_direct_child(ObClient *parent, ObClient *child)
@ -3378,7 +3385,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
self->desktop != screen_desktop)
{
if (here)
client_set_desktop(self, screen_desktop, FALSE);
client_set_desktop(self, screen_desktop, FALSE, FALSE);
else
screen_set_desktop(self->desktop, FALSE);
} else if (!self->frame->visible)
@ -3426,6 +3433,26 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
}
}
static void client_bring_non_application_windows_recursive(ObClient *self,
guint desktop)
{
GSList *it;
for (it = self->transients; it; it = g_slist_next(it))
client_bring_non_application_windows_recursive(it->data, desktop);
if (client_normal(self) && !client_application(self) &&
self->desktop != desktop && self->desktop != DESKTOP_ALL)
{
client_set_desktop(self, desktop, FALSE, TRUE);
}
}
void client_bring_non_application_windows(ObClient *self)
{
client_bring_non_application_windows_recursive(self, self->desktop);
}
void client_raise(ObClient *self)
{
action_run_string("Raise", self, CurrentTime);

View file

@ -465,8 +465,13 @@ void client_kill(ObClient *self);
/*! Sends the window to the specified desktop
@param donthide If TRUE, the window will not be shown/hidden after its
desktop has been changed. Generally this should be FALSE. */
void client_set_desktop(ObClient *self, guint target, gboolean donthide);
desktop has been changed. Generally this should be FALSE.
@param focus_nonintrusive If TRUE, the window will not be moved in the
focus order at all. Do this when moving windows to a desktop in
the "background" or something. It can be used to make a window share
multiple desktops. Generally this should be FALSE. */
void client_set_desktop(ObClient *self, guint target,
gboolean donthide, gboolean focus_nonintrusive);
/*! Show the client if it should be shown. */
void client_show(ObClient *self);
@ -520,6 +525,10 @@ gboolean client_focus(ObClient *self);
*/
void client_activate(ObClient *self, gboolean here, gboolean user);
/*! Bring all of its non-application windows to its desktop. These are the
utility and stuff windows. */
void client_bring_non_application_windows(ObClient *client);
/*! Calculates the stacking layer for the client window */
void client_calc_layer(ObClient *self);

View file

@ -504,6 +504,7 @@ static void event_process(const XEvent *ec, gpointer data)
frame_adjust_focus(client->frame, TRUE);
focus_set_client(client);
client_calc_layer(client);
client_bring_non_application_windows(client);
}
} else if (e->type == FocusOut) {
gboolean nomove = FALSE;
@ -1024,7 +1025,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
(unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
client_set_desktop(client, (unsigned)e->xclient.data.l[0],
FALSE);
FALSE, FALSE);
} else if (msgtype == prop_atoms.net_wm_state) {
/* can't compress these */
ob_debug("net_wm_state %s %ld %ld for 0x%lx\n",

View file

@ -438,7 +438,7 @@ void screen_set_num_desktops(guint num)
for (it = client_list; it; it = g_list_next(it)) {
ObClient *c = it->data;
if (c->desktop >= num && c->desktop != DESKTOP_ALL)
client_set_desktop(c, num - 1, FALSE);
client_set_desktop(c, num - 1, FALSE, FALSE);
}
/* change our struts/area to match (after moving windows) */
@ -473,7 +473,7 @@ void screen_set_desktop(guint num, gboolean dofocus)
ob_debug("Moving to desktop %d\n", num+1);
if (moveresize_client)
client_set_desktop(moveresize_client, num, TRUE);
client_set_desktop(moveresize_client, num, TRUE, FALSE);
/* show windows before hiding the rest to lessen the enter/leave events */
@ -485,6 +485,27 @@ void screen_set_desktop(guint num, gboolean dofocus)
}
}
/* have to try focus here because when you leave an empty desktop
there is no focus out to watch for
do this before hiding the windows so if helper windows are coming
with us, they don't get hidden
*/
if (dofocus && (c = focus_fallback_target(TRUE, focus_client))) {
/* only do the flicker reducing stuff ahead of time if we are going
to call xsetinputfocus on the window ourselves. otherwise there is
no guarantee the window will actually take focus.. */
if (c->can_focus) {
/* do this here so that if you switch desktops to a window with
helper windows then the helper windows won't flash */
client_bring_non_application_windows(c);
/* reduce flicker by hiliting now rather than waiting for the
server FocusIn event */
frame_adjust_focus(c->frame, TRUE);
}
client_focus(c);
}
/* hide windows from bottom to top */
for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {
if (WINDOW_IS_CLIENT(it->data)) {
@ -493,15 +514,6 @@ void screen_set_desktop(guint num, gboolean dofocus)
}
}
/* have to try focus here because when you leave an empty desktop
there is no focus out to watch for */
if (dofocus && (c = focus_fallback_target(TRUE, focus_client))) {
/* reduce flicker by hiliting now rather than waiting for the server
FocusIn event */
frame_adjust_focus(c->frame, TRUE);
client_focus(c);
}
event_ignore_queued_enters();
if (event_curtime != CurrentTime)