{
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)
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);
}
!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);
}
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);
}
void client_set_desktop_recursive(ObClient *self,
- guint target, gboolean donthide)
+ guint target,
+ gboolean donthide,
+ gboolean focus_nonintrusive)
{
guint old;
GSList *it;
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;
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;
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)
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)
}
}
+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);
/*! 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);
*/
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);
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;
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",
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) */
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 */
}
}
+ /* 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)) {
}
}
- /* 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)