- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
- windows = g_new(Window, size);
- win_it = windows;
- for (it = client_list; it != NULL; it = it->next, ++win_it)
- *win_it = ((ObClient*)it->data)->window;
+ windows = g_new(Window, size);
+ win_it = windows;
+ for (it = client_list; it; it = g_list_next(it), ++win_it)
+ *win_it = ((ObClient*)it->data)->window;
PROP_SETA32(RootWindow(ob_display, ob_screen),
net_client_list, window, (guint32*)windows, size);
if (windows)
PROP_SETA32(RootWindow(ob_display, ob_screen),
net_client_list, window, (guint32*)windows, size);
if (windows)
-void client_foreach_transient(ObClient *self, ObClientForeachFunc func, void *data)
-{
- GSList *it;
-
- for (it = self->transients; it; it = it->next) {
- if (!func(it->data, data)) return;
- client_foreach_transient(it->data, func, data);
- }
-}
-
-void client_foreach_ancestor(ObClient *self, ObClientForeachFunc func, void *data)
-{
- if (self->transient_for) {
- if (self->transient_for != OB_TRAN_GROUP) {
- if (!func(self->transient_for, data)) return;
- client_foreach_ancestor(self->transient_for, func, data);
- } else {
- GSList *it;
-
- for (it = self->group->members; it; it = it->next)
- if (it->data != self &&
- !((ObClient*)it->data)->transient_for) {
- if (!func(it->data, data)) return;
- client_foreach_ancestor(it->data, func, data);
- }
- }
- }
-}
+ void client_foreach_transient(ObClient *self, ObClientForeachFunc func, void *data)
+ {
+ GSList *it;
+
+ for (it = self->transients; it; it = g_slist_next(it)) {
+ if (!func(it->data, data)) return;
+ client_foreach_transient(it->data, func, data);
+ }
+ }
+
+ void client_foreach_ancestor(ObClient *self, ObClientForeachFunc func, void *data)
+ {
+ if (self->transient_for) {
+ if (self->transient_for != OB_TRAN_GROUP) {
+ if (!func(self->transient_for, data)) return;
+ client_foreach_ancestor(self->transient_for, func, data);
+ } else {
+ GSList *it;
+
+ for (it = self->group->members; it; it = g_slist_next(it))
+ if (it->data != self &&
+ !((ObClient*)it->data)->transient_for) {
+ if (!func(it->data, data)) return;
+ client_foreach_ancestor(it->data, func, data);
+ }
+ }
+ }
+ }
- if (children[i] == None) continue;
- wmhints = XGetWMHints(ob_display, children[i]);
- if (wmhints) {
- if ((wmhints->flags & IconWindowHint) &&
- (wmhints->icon_window != children[i]))
- for (j = 0; j < nchild; j++)
- if (children[j] == wmhints->icon_window) {
- children[j] = None;
- break;
- }
- XFree(wmhints);
- }
+ if (children[i] == None) continue;
+ wmhints = XGetWMHints(ob_display, children[i]);
+ if (wmhints) {
+ if ((wmhints->flags & IconWindowHint) &&
+ (wmhints->icon_window != children[i]))
+ for (j = 0; j < nchild; j++)
+ if (children[j] == wmhints->icon_window) {
+ children[j] = None;
+ break;
+ }
+ XFree(wmhints);
+ }
- if (children[i] == None)
- continue;
- if (XGetWindowAttributes(ob_display, children[i], &attrib)) {
- if (attrib.override_redirect) continue;
+ if (children[i] == None)
+ continue;
+ if (XGetWindowAttributes(ob_display, children[i], &attrib)) {
+ if (attrib.override_redirect) continue;
/* check if it has already been unmapped by the time we started mapping
the grab does a sync so we don't have to here */
if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
/* check if it has already been unmapped by the time we started mapping
the grab does a sync so we don't have to here */
if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e)) {
- XPutBackEvent(ob_display, &e);
+ XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e)) {
+ XPutBackEvent(ob_display, &e);
attrib_set.event_mask = CLIENT_EVENTMASK;
attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
XChangeWindowAttributes(ob_display, window,
attrib_set.event_mask = CLIENT_EVENTMASK;
attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
XChangeWindowAttributes(ob_display, window,
stacking_add(CLIENT_AS_WINDOW(self));
client_restore_session_stacking(self);
/* focus the new window? */
if (ob_state() != OB_STATE_STARTING &&
stacking_add(CLIENT_AS_WINDOW(self));
client_restore_session_stacking(self);
/* focus the new window? */
if (ob_state() != OB_STATE_STARTING &&
/* note the check against Type_Normal/Dialog, not client_normal(self),
which would also include other types. in this case we want more
strict rules for focus */
/* note the check against Type_Normal/Dialog, not client_normal(self),
which would also include other types. in this case we want more
strict rules for focus */
- if (activate) client_focus(self);
+ if (activate) {
+ /* if using focus_delay, stop the timer now so that focus doesn't go
+ moving on us */
+ event_halt_focus_delay();
+
+ client_focus(self);
+ /* since focus can change the stacking orders, if we focus the window
+ then the standard raise it gets is not enough, we need to queue one
+ for after the focus change takes place */
+ client_raise(self);
+ }
+ for (it = client_destructors; it; it = g_slist_next(it)) {
+ Destructor *d = it->data;
+ d->func(self, d->data);
+ }
+
+ if (focus_client == self) {
+ XEvent e;
+
+ /* focus the last focused window on the desktop, and ignore enter
+ events from the unmap so it doesnt mess with the focus */
+ while (XCheckTypedEvent(ob_display, EnterNotify, &e));
+ /* remove these flags so we don't end up getting focused in the
+ fallback! */
+ self->can_focus = FALSE;
+ self->focus_notify = FALSE;
+ self->modal = FALSE;
+ client_unfocus(self);
+ }
+
- for (it = client_destructors; it; it = g_slist_next(it)) {
- GDestroyNotify func = (GDestroyNotify) it->data;
- func(self);
- }
-
- if (focus_client == self) {
- XEvent e;
-
- /* focus the last focused window on the desktop, and ignore enter
- events from the unmap so it doesnt mess with the focus */
- while (XCheckTypedEvent(ob_display, EnterNotify, &e));
- client_unfocus(self);
- }
-
- /* these values should not be persisted across a window
- unmapping/mapping */
- PROP_ERASE(self->window, net_wm_desktop);
- PROP_ERASE(self->window, net_wm_state);
- PROP_ERASE(self->window, wm_state);
+ /* these values should not be persisted across a window
+ unmapping/mapping */
+ PROP_ERASE(self->window, net_wm_desktop);
+ PROP_ERASE(self->window, net_wm_state);
+ PROP_ERASE(self->window, wm_state);
- /* if we're left in an iconic state, the client wont be mapped. this is
- bad, since we will no longer be managing the window on restart */
- if (self->iconic)
- XMapWindow(ob_display, self->window);
+ /* if we're left in an unmapped state, the client wont be mapped. this
+ is bad, since we will no longer be managing the window on restart */
+ XMapWindow(ob_display, self->window);
- /* move the client so it is back it the right spot _with_ its
- border! */
- if (x != oldx || y != oldy)
- XMoveWindow(ob_display, self->window, x, y);
+ /* move the client so it is back it the right spot _with_ its
+ border! */
+ if (x != oldx || y != oldy)
+ XMoveWindow(ob_display, self->window, x, y);
/* got the type, the mwmhints, the protocols, and the normal hints
(min/max sizes), so we're ready to set up the decorations/functions */
/* got the type, the mwmhints, the protocols, and the normal hints
(min/max sizes), so we're ready to set up the decorations/functions */
- }
- if (!trdesk) {
- /* try get from the startup-notification protocol */
- if (sn_get_desktop(self->startup_id, &self->desktop)) {
- if (self->desktop >= screen_num_desktops &&
- self->desktop != DESKTOP_ALL)
- self->desktop = screen_num_desktops - 1;
- } else
- /* defaults to the current desktop */
- self->desktop = screen_desktop;
- }
+ }
+ if (!trdesk) {
+ /* try get from the startup-notification protocol */
+ if (sn_get_desktop(self->startup_id, &self->desktop)) {
+ if (self->desktop >= screen_num_desktops &&
+ self->desktop != DESKTOP_ALL)
+ self->desktop = screen_num_desktops - 1;
+ } else
+ /* defaults to the current desktop */
+ self->desktop = screen_desktop;
+ }
+
+ if (!(self->above || self->below)) {
+ if (self->group) {
+ /* apply stuff from the group */
+ GSList *it;
+ gint layer = -2;
+
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if (c != self && !client_search_transient(self, c) &&
+ client_normal(self) && client_normal(c))
+ {
+ layer = MAX(layer,
+ (c->above ? 1 : (c->below ? -1 : 0)));
+ }
+ }
+ switch (layer) {
+ case -1:
+ self->below = TRUE;
+ break;
+ case -2:
+ case 0:
+ break;
+ case 1:
+ self->above = TRUE;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ }
+ }
- XShapeQueryExtents(ob_display, self->window, &s, &foo,
- &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
- &ufoo);
- self->shaped = (s != 0);
+ XShapeQueryExtents(ob_display, self->window, &s, &foo,
+ &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
+ &ufoo);
+ self->shaped = (s != 0);
for (it = self->group->members; it; it = g_slist_next(it)) {
ObClient *c = it->data;
if (c != self && !c->transient_for)
c->transients = g_slist_remove(c->transients, self);
}
} else if (self->transient_for != NULL) { /* transient of window */
for (it = self->group->members; it; it = g_slist_next(it)) {
ObClient *c = it->data;
if (c != self && !c->transient_for)
c->transients = g_slist_remove(c->transients, self);
}
} else if (self->transient_for != NULL) { /* transient of window */
- if (num >= OB_MWM_ELEMENTS) {
- self->mwmhints.flags = hints[0];
- self->mwmhints.functions = hints[1];
- self->mwmhints.decorations = hints[2];
- }
- g_free(hints);
+ if (num >= OB_MWM_ELEMENTS) {
+ self->mwmhints.flags = hints[0];
+ self->mwmhints.functions = hints[1];
+ self->mwmhints.decorations = hints[2];
+ }
+ g_free(hints);
- /* use the first value that we know about in the array */
- for (i = 0; i < num; ++i) {
- if (val[i] == prop_atoms.net_wm_window_type_desktop)
- self->type = OB_CLIENT_TYPE_DESKTOP;
- else if (val[i] == prop_atoms.net_wm_window_type_dock)
- self->type = OB_CLIENT_TYPE_DOCK;
- else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
- self->type = OB_CLIENT_TYPE_TOOLBAR;
- else if (val[i] == prop_atoms.net_wm_window_type_menu)
- self->type = OB_CLIENT_TYPE_MENU;
- else if (val[i] == prop_atoms.net_wm_window_type_utility)
- self->type = OB_CLIENT_TYPE_UTILITY;
- else if (val[i] == prop_atoms.net_wm_window_type_splash)
- self->type = OB_CLIENT_TYPE_SPLASH;
- else if (val[i] == prop_atoms.net_wm_window_type_dialog)
- self->type = OB_CLIENT_TYPE_DIALOG;
- else if (val[i] == prop_atoms.net_wm_window_type_normal)
- self->type = OB_CLIENT_TYPE_NORMAL;
- else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
- /* prevent this window from getting any decor or
- functionality */
- self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
- OB_MWM_FLAG_DECORATIONS);
- self->mwmhints.decorations = 0;
- self->mwmhints.functions = 0;
- }
- if (self->type != (ObClientType) -1)
- break; /* grab the first legit type */
- }
- g_free(val);
+ /* use the first value that we know about in the array */
+ for (i = 0; i < num; ++i) {
+ if (val[i] == prop_atoms.net_wm_window_type_desktop)
+ self->type = OB_CLIENT_TYPE_DESKTOP;
+ else if (val[i] == prop_atoms.net_wm_window_type_dock)
+ self->type = OB_CLIENT_TYPE_DOCK;
+ else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
+ self->type = OB_CLIENT_TYPE_TOOLBAR;
+ else if (val[i] == prop_atoms.net_wm_window_type_menu)
+ self->type = OB_CLIENT_TYPE_MENU;
+ else if (val[i] == prop_atoms.net_wm_window_type_utility)
+ self->type = OB_CLIENT_TYPE_UTILITY;
+ else if (val[i] == prop_atoms.net_wm_window_type_splash)
+ self->type = OB_CLIENT_TYPE_SPLASH;
+ else if (val[i] == prop_atoms.net_wm_window_type_dialog)
+ self->type = OB_CLIENT_TYPE_DIALOG;
+ else if (val[i] == prop_atoms.net_wm_window_type_normal)
+ self->type = OB_CLIENT_TYPE_NORMAL;
+ else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
+ /* prevent this window from getting any decor or
+ functionality */
+ self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
+ OB_MWM_FLAG_DECORATIONS);
+ self->mwmhints.decorations = 0;
+ self->mwmhints.functions = 0;
+ }
+ if (self->type != (ObClientType) -1)
+ break; /* grab the first legit type */
+ }
+ g_free(val);
- /*the window type hint was not set, which means we either classify
- ourself as a normal window or a dialog, depending on if we are a
- transient. */
- if (self->transient)
- self->type = OB_CLIENT_TYPE_DIALOG;
- else
- self->type = OB_CLIENT_TYPE_NORMAL;
+ /*the window type hint was not set, which means we either classify
+ ourself as a normal window or a dialog, depending on if we are a
+ transient. */
+ if (self->transient)
+ self->type = OB_CLIENT_TYPE_DIALOG;
+ else
+ self->type = OB_CLIENT_TYPE_NORMAL;
self->delete_window = FALSE;
if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
self->delete_window = FALSE;
if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
- for (i = 0; i < num_return; ++i) {
- if (proto[i] == prop_atoms.wm_delete_window) {
- /* this means we can request the window to close */
- self->delete_window = TRUE;
- } else if (proto[i] == prop_atoms.wm_take_focus)
- /* if this protocol is requested, then the window will be
- notified whenever we want it to receive focus */
- self->focus_notify = TRUE;
- }
- g_free(proto);
+ for (i = 0; i < num_return; ++i) {
+ if (proto[i] == prop_atoms.wm_delete_window) {
+ /* this means we can request the window to close */
+ self->delete_window = TRUE;
+ } else if (proto[i] == prop_atoms.wm_take_focus)
+ /* if this protocol is requested, then the window will be
+ notified whenever we want it to receive focus */
+ self->focus_notify = TRUE;
+ }
+ g_free(proto);
- /* if the client has a frame, i.e. has already been mapped and
- is changing its gravity */
- if (self->frame && self->gravity != oldgravity) {
- /* move our idea of the client's position based on its new
- gravity */
- self->area.x = self->frame->area.x;
- self->area.y = self->frame->area.y;
- frame_frame_gravity(self->frame, &self->area.x, &self->area.y);
- }
- }
+ /* if the client has a frame, i.e. has already been mapped and
+ is changing its gravity */
+ if (self->frame && self->gravity != oldgravity) {
+ /* move our idea of the client's position based on its new
+ gravity */
+ self->area.x = self->frame->area.x;
+ self->area.y = self->frame->area.y;
+ frame_frame_gravity(self->frame, &self->area.x, &self->area.y);
+ }
+ }
- /* normal windows retain all of the possible decorations and
- functionality, and are the only windows that you can fullscreen */
- self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
- break;
+ /* normal windows retain all of the possible decorations and
+ functionality, and are the only windows that you can fullscreen */
+ self->functions |= OB_CLIENT_FUNC_FULLSCREEN;
+ break;
- if (! (self->mwmhints.functions & OB_MWM_FUNC_ALL)) {
- if (! (self->mwmhints.functions & OB_MWM_FUNC_RESIZE))
- self->functions &= ~OB_CLIENT_FUNC_RESIZE;
- if (! (self->mwmhints.functions & OB_MWM_FUNC_MOVE))
- self->functions &= ~OB_CLIENT_FUNC_MOVE;
+ if (! (self->mwmhints.functions & OB_MWM_FUNC_ALL)) {
+ if (! (self->mwmhints.functions & OB_MWM_FUNC_RESIZE))
+ self->functions &= ~OB_CLIENT_FUNC_RESIZE;
+ if (! (self->mwmhints.functions & OB_MWM_FUNC_MOVE))
+ self->functions &= ~OB_CLIENT_FUNC_MOVE;
- if (! (self->mwmhints.functions & OB_MWM_FUNC_ICONIFY))
- self->functions &= ~OB_CLIENT_FUNC_ICONIFY;
- if (! (self->mwmhints.functions & OB_MWM_FUNC_MAXIMIZE))
- self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
+ if (! (self->mwmhints.functions & OB_MWM_FUNC_ICONIFY))
+ self->functions &= ~OB_CLIENT_FUNC_ICONIFY;
+ if (! (self->mwmhints.functions & OB_MWM_FUNC_MAXIMIZE))
+ self->functions &= ~OB_CLIENT_FUNC_MAXIMIZE;
/* desktop windows are kept on all desktops */
if (self->type != OB_CLIENT_TYPE_DESKTOP)
actions[num++] = prop_atoms.net_wm_action_change_desktop;
if (self->functions & OB_CLIENT_FUNC_SHADE)
/* desktop windows are kept on all desktops */
if (self->type != OB_CLIENT_TYPE_DESKTOP)
actions[num++] = prop_atoms.net_wm_action_change_desktop;
if (self->functions & OB_CLIENT_FUNC_SHADE)
- 0, 0, 0, 0, 0, 0, 0, 0);
+ a->y, a->y + a->height - 1,
+ a->x, a->x + a->width - 1,
+ a->y, a->y + a->height - 1,
+ a->x, a->x + a->width - 1);
} else if (PROP_GETA32(self->window, kwm_win_icon,
kwm_win_icon, &data, &num)) {
if (num == 2) {
} else if (PROP_GETA32(self->window, kwm_win_icon,
kwm_win_icon, &data, &num)) {
if (num == 2) {
}
}
/* this function checks the whole tree, the client_search_focus_tree~
does not, so we need to check this window */
if (client_focused(self))
}
}
/* this function checks the whole tree, the client_search_focus_tree~
does not, so we need to check this window */
if (client_focused(self))
- if (self->iconic) return FALSE;
- else if (!(self->desktop == screen_desktop ||
- self->desktop == DESKTOP_ALL)) return FALSE;
- else if (client_normal(self) && screen_showing_desktop) return FALSE;
+ if (self->iconic)
+ return FALSE;
+ if (client_normal(self) && screen_showing_desktop)
+ return FALSE;
+ /*
+ if (self->transient_for) {
+ if (self->transient_for != OB_TRAN_GROUP)
+ return client_should_show(self->transient_for);
+ else {
+ GSList *it;
+
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if (c != self && !c->transient_for) {
+ if (client_should_show(c))
+ return TRUE;
+ }
+ }
+ }
+ }
+ */
+ if (self->desktop == screen_desktop || self->desktop == DESKTOP_ALL)
+ return TRUE;
- if (savearea)
- self->pre_max_area = self->area;
+ if (savearea) {
+ if ((dir == 0 || dir == 1) && !self->max_horz) { /* horz */
+ RECT_SET(self->pre_max_area,
+ self->area.x, self->pre_max_area.y,
+ self->area.width, self->pre_max_area.height);
+ }
+ if ((dir == 0 || dir == 2) && !self->max_vert) { /* vert */
+ RECT_SET(self->pre_max_area,
+ self->pre_max_area.x, self->area.y,
+ self->pre_max_area.width, self->area.height);
+ }
+ }
- for (it = self->transients; it != NULL; it = it->next) {
- ObClient *c = it->data;
- if ((ret = client_search_modal_child(c))) return ret;
- if (c->modal) return c;
+ for (it = self->transients; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if ((ret = client_search_modal_child(c))) return ret;
+ if (c->modal) return c;
XSync(ob_display, FALSE); /* get all events on the server */
if (XCheckTypedWindowEvent(ob_display, self->window, DestroyNotify, &e) ||
XSync(ob_display, FALSE); /* get all events on the server */
if (XCheckTypedWindowEvent(ob_display, self->window, DestroyNotify, &e) ||
- XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &e)) {
- XPutBackEvent(ob_display, &e);
- return FALSE;
+ XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &e)) {
+ XPutBackEvent(ob_display, &e);
+ return FALSE;
{
gboolean shaded = self->shaded;
gboolean fullscreen = self->fullscreen;
gboolean undecorated = self->undecorated;
gboolean max_horz = self->max_horz;
gboolean max_vert = self->max_vert;
{
gboolean shaded = self->shaded;
gboolean fullscreen = self->fullscreen;
gboolean undecorated = self->undecorated;
gboolean max_horz = self->max_horz;
gboolean max_vert = self->max_vert;
client_shade(self, shaded);
if (undecorated != self->undecorated)
client_set_undecorated(self, undecorated);
client_shade(self, shaded);
if (undecorated != self->undecorated)
client_set_undecorated(self, undecorated);
/* do a check to see if the window has already been unmapped or destroyed
do this intelligently while watching out for unmaps we've generated
(ignore_unmaps > 0) */
if (XCheckTypedWindowEvent(ob_display, self->window,
/* do a check to see if the window has already been unmapped or destroyed
do this intelligently while watching out for unmaps we've generated
(ignore_unmaps > 0) */
if (XCheckTypedWindowEvent(ob_display, self->window,
- XEvent ce;
- ce.xclient.type = ClientMessage;
- ce.xclient.message_type = prop_atoms.wm_protocols;
- ce.xclient.display = ob_display;
- ce.xclient.window = self->window;
- ce.xclient.format = 32;
- ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
- ce.xclient.data.l[1] = event_lasttime;
- ce.xclient.data.l[2] = 0l;
- ce.xclient.data.l[3] = 0l;
- ce.xclient.data.l[4] = 0l;
- XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
+ XEvent ce;
+ ce.xclient.type = ClientMessage;
+ ce.xclient.message_type = prop_atoms.wm_protocols;
+ ce.xclient.display = ob_display;
+ ce.xclient.window = self->window;
+ ce.xclient.format = 32;
+ ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
+ ce.xclient.data.l[1] = event_lasttime;
+ ce.xclient.data.l[2] = 0l;
+ ce.xclient.data.l[3] = 0l;
+ ce.xclient.data.l[4] = 0l;
+ XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
- stacking_raise(CLIENT_AS_WINDOW(self));
+
+ /* we do this an action here. this is rather important. this is because
+ we want the results from the focus change to take place BEFORE we go
+ about raising the window. when a fullscreen window loses focus, we need
+ this or else the raise wont be able to raise above the to-lose-focus
+ fullscreen window. */
+ client_raise(self);
+}
+
+void client_raise(ObClient *self)
+{
+ action_run_string("Raise", self);
+}
+
+void client_lower(ObClient *self)
+{
+ action_run_string("Raise", self);
- unsigned long size, smallest = 0xffffffff, largest = 0, si = 0, li = 0;
+ gulong size, smallest = 0xffffffff, largest = 0, si = 0, li = 0;
+
+ if (!self->nicons) {
+ ObClientIcon *parent = NULL;
+
+ if (self->transient_for) {
+ if (self->transient_for != OB_TRAN_GROUP)
+ parent = client_icon_recursive(self->transient_for, w, h);
+ else {
+ GSList *it;
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+ if (c != self && !c->transient_for) {
+ if ((parent = client_icon_recursive(c, w, h)))
+ break;
+ }
+ }
+ }
+ }
+
+ return parent;
+ }
+ObClient *client_search_focus_parent(ObClient *self)
+{
+ if (self->transient_for) {
+ if (self->transient_for != OB_TRAN_GROUP) {
+ if (client_focused(self->transient_for))
+ return self->transient_for;
+ } else {
+ GSList *it;
+
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+
+ /* checking transient_for prevents infinate loops! */
+ if (c != self && !c->transient_for)
+ if (client_focused(c))
+ return c;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+ObClient *client_search_parent(ObClient *self, ObClient *search)
+{
+ if (self->transient_for) {
+ if (self->transient_for != OB_TRAN_GROUP) {
+ if (self->transient_for == search)
+ return search;
+ } else {
+ GSList *it;
+
+ for (it = self->group->members; it; it = g_slist_next(it)) {
+ ObClient *c = it->data;
+
+ /* checking transient_for prevents infinate loops! */
+ if (c != self && !c->transient_for)
+ if (c == search)
+ return search;
+ }
+ }
+ }
+
+ return NULL;
+}
+
- for(it = g_list_first(client_list); it; it = it->next) {
- int his_edge_start, his_edge_end, his_offset;
+ /* default: bottom of screen */
+ dest = a->y + a->height;
+
+ for(it = client_list; it; it = g_list_next(it)) {
+ gint his_edge_start, his_edge_end, his_offset;