#include "client.h"
-#include "grab.h"
#include "focus.h"
#include "moveresize.h"
#include "menu.h"
#include "prop.h"
#include "stacking.h"
#include "frame.h"
-#include "framerender.h"
#include "screen.h"
#include "action.h"
#include "dispatch.h"
}
}
-static void popup_cycle(Client *c, gboolean hide)
-{
- XSetWindowAttributes attrib;
- static Window coords = None;
-
- if (coords == None) {
- attrib.override_redirect = TRUE;
- coords = XCreateWindow(ob_display, ob_root,
- 0, 0, 1, 1, 0, render_depth, InputOutput,
- render_visual, CWOverrideRedirect, &attrib);
- g_assert(coords != None);
-
- grab_pointer(TRUE, None);
-
- XMapWindow(ob_display, coords);
- }
-
- if (hide) {
- XDestroyWindow(ob_display, coords);
- coords = None;
-
- grab_pointer(FALSE, None);
- } else {
- Rect *a;
- Size s;
-
- a = screen_area(c->desktop);
-
- framerender_size_popup_label(c->title, &s);
- XMoveResizeWindow(ob_display, coords,
- a->x + (a->width - s.width) / 2,
- a->y + (a->height - s.height) / 2,
- s.width, s.height);
- framerender_popup_label(coords, &s, c->title);
- }
-}
-
void action_cycle_windows(union ActionData *data)
{
Client *c;
c = focus_cycle(data->cycle.forward, data->cycle.linear, data->cycle.final,
data->cycle.cancel);
- popup_cycle(c, !c || data->cycle.final || data->cycle.cancel);
}
XWindowAttributes attrib;
XSetWindowAttributes attrib_set;
/* XWMHints *wmhint; */
- guint i;
grab_server(TRUE);
g_hash_table_insert(client_map, &self->window, self);
/* update the focus lists */
- if (self->desktop == DESKTOP_ALL) {
- for (i = 0; i < screen_num_desktops; ++i)
- focus_order[i] = g_list_insert(focus_order[i], self, 1);
- } else {
- i = self->desktop;
- focus_order[i] = g_list_insert(focus_order[i], self, 1);
- }
+ focus_order_add_new(self);
stacking_raise(self);
void client_unmanage(Client *self)
{
- guint i;
int j;
GSList *it;
g_hash_table_remove(client_map, &self->window);
/* update the focus lists */
- if (self->desktop == DESKTOP_ALL) {
- for (i = 0; i < screen_num_desktops; ++i)
- focus_order[i] = g_list_remove(focus_order[i], self);
- } else {
- i = self->desktop;
- focus_order[i] = g_list_remove(focus_order[i], self);
- }
+ focus_order_remove(self);
/* once the client is out of the list, update the struts to remove it's
influence */
/* we unmap the client itself so that we can get MapRequest events,
and because the ICCCM tells us to! */
XUnmapWindow(ob_display, self->window);
+
+ /* update the focus lists.. iconic windows go to the bottom */
+ focus_order_to_bottom(self);
} else {
if (curdesk)
client_set_desktop(self, screen_desktop, FALSE);
void client_set_desktop(Client *self, guint target, gboolean donthide)
{
- guint old, i;
+ guint old;
if (target == self->desktop) return;
g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
+ /* remove from the old desktop(s) */
+ focus_order_remove(self);
+
old = self->desktop;
self->desktop = target;
PROP_SET32(self->window, net_wm_desktop, cardinal, target);
stacking_raise(self);
screen_update_struts();
- /* update the focus lists */
- if (old == DESKTOP_ALL) {
- for (i = 0; i < screen_num_desktops; ++i)
- focus_order[i] = g_list_remove(focus_order[i], self);
- } else
- focus_order[old] = g_list_remove(focus_order[old], self);
- if (target == DESKTOP_ALL) {
- for (i = 0; i < screen_num_desktops; ++i) {
- if (config_focus_new)
- focus_order[i] = g_list_prepend(focus_order[i], self);
- else
- focus_order[i] = g_list_append(focus_order[i], self);
- }
- } else {
- if (config_focus_new)
- focus_order[target] = g_list_prepend(focus_order[target], self);
- else
- focus_order[target] = g_list_append(focus_order[target], self);
- }
+ /* add to the new desktop(s) */
+ if (config_focus_new)
+ focus_order_to_top(self);
+ else
+ focus_order_to_bottom(self);
dispatch_client(Event_Client_Desktop, self, target, old);
}
return self;
}
-gboolean client_focusable(Client *self)
-{
- /* won't try focus if the client doesn't want it, or if the window isn't
- visible on the screen */
- return self->frame->visible &&
- (self->can_focus || self->focus_notify);
-}
-
gboolean client_focus(Client *self)
{
XEvent ev;
- guint i;
/* choose the correct target */
self = client_focus_target(self);
if (self->desktop != DESKTOP_ALL && self->desktop != screen_desktop) {
/* update the focus lists */
- if (self->desktop == DESKTOP_ALL) {
- for (i = 0; i < screen_num_desktops; ++i) {
- focus_order[i] = g_list_remove(focus_order[i], self);
- focus_order[i] = g_list_prepend(focus_order[i], self);
- }
- } else {
- i = self->desktop;
- focus_order[i] = g_list_remove(focus_order[i], self);
- focus_order[i] = g_list_prepend(focus_order[i], self);
- }
+ focus_order_to_top(self);
return FALSE;
}
- if (!client_focusable(self))
+ if (!((self->can_focus || self->focus_notify) &&
+ (self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ !self->iconic))
return FALSE;
/* do a check to see if the window has already been unmapped or destroyed
Client passed to it or another Client if appropriate. */
Client *client_focus_target(Client *self);
-/* Returns if a client can be focused or not */
-gboolean client_focusable(Client *self);
-
/*! Attempt to focus the client window */
gboolean client_focus(Client *self);
#include "event.h"
#include "openbox.h"
+#include "grab.h"
+#include "framerender.h"
#include "client.h"
#include "config.h"
#include "frame.h"
Client *ret;
for (it = c->transients; it; it = it->next) {
- g_message("looking");
if (it->data == top) return NULL;
ret = find_transient_recursive(it->data, top, skip);
if (ret && ret != skip && client_normal(ret)) return ret;
if (it->data != skip && client_normal(it->data)) return it->data;
- g_message("not found");
}
return NULL;
}
focus_set_client(NULL);
}
+static void popup_cycle(Client *c, gboolean show)
+{
+ XSetWindowAttributes attrib;
+ static Window coords = None;
+
+ if (coords == None) {
+ attrib.override_redirect = TRUE;
+ coords = XCreateWindow(ob_display, ob_root,
+ 0, 0, 1, 1, 0, render_depth, InputOutput,
+ render_visual, CWOverrideRedirect, &attrib);
+ g_assert(coords != None);
+
+ grab_pointer(TRUE, None);
+
+ XMapWindow(ob_display, coords);
+ }
+
+ if (!show) {
+ XDestroyWindow(ob_display, coords);
+ coords = None;
+
+ grab_pointer(FALSE, None);
+ } else {
+ Rect *a;
+ Size s;
+
+ a = screen_area(c->desktop);
+
+ framerender_size_popup_label(c->title, &s);
+ XMoveResizeWindow(ob_display, coords,
+ a->x + (a->width - s.width) / 2,
+ a->y + (a->height - s.height) / 2,
+ s.width, s.height);
+ framerender_popup_label(coords, &s, c->title);
+ }
+}
+
Client *focus_cycle(gboolean forward, gboolean linear, gboolean done,
gboolean cancel)
{
goto done_cycle;
} else if (done) {
if (focus_cycle_target) {
+ if (focus_cycle_target->iconic)
+ client_iconify(focus_cycle_target, FALSE, FALSE);
client_focus(focus_cycle_target);
stacking_raise(focus_cycle_target);
}
do {
if (forward) {
it = it->next;
- if (it == NULL) it = list;
+ if (it == NULL) it = g_list_first(list);
} else {
it = it->prev;
if (it == NULL) it = g_list_last(list);
}
ft = client_focus_target(it->data);
- if (ft == it->data && client_normal(ft) && client_focusable(ft)) {
+ if (ft == it->data && client_normal(ft) &&
+ (ft->can_focus || ft->focus_notify) &&
+ (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)) {
if (focus_cycle_target)
frame_adjust_focus(focus_cycle_target->frame, FALSE);
- else if (focus_client)
- frame_adjust_focus(focus_client->frame, FALSE);
focus_cycle_target = ft;
frame_adjust_focus(focus_cycle_target->frame, TRUE);
+ popup_cycle(ft, TRUE);
return ft;
}
} while (it != start);
- return NULL;
done_cycle:
t = NULL;
focus_cycle_target = NULL;
g_list_free(order);
order = NULL;
+ popup_cycle(ft, FALSE);
return NULL;
}
+
+void focus_order_add_new(Client *c)
+{
+ guint d, i;
+
+ if (c->iconic)
+ focus_order_to_top(c);
+ else {
+ d = c->desktop;
+ if (d == DESKTOP_ALL) {
+ for (i = 0; i < screen_num_desktops; ++i) {
+ if (focus_order[i] && ((Client*)focus_order[i]->data)->iconic)
+ focus_order[i] = g_list_insert(focus_order[i], c, 0);
+ else
+ focus_order[i] = g_list_insert(focus_order[i], c, 1);
+ }
+ } else
+ if (focus_order[d] && ((Client*)focus_order[d]->data)->iconic)
+ focus_order[d] = g_list_insert(focus_order[d], c, 0);
+ else
+ focus_order[d] = g_list_insert(focus_order[d], c, 1);
+ }
+}
+
+void focus_order_remove(Client *c)
+{
+ guint d, i;
+
+ d = c->desktop;
+ if (d == DESKTOP_ALL) {
+ for (i = 0; i < screen_num_desktops; ++i)
+ focus_order[i] = g_list_remove(focus_order[i], c);
+ } else
+ focus_order[d] = g_list_remove(focus_order[d], c);
+}
+
+static void to_top(Client *c, guint d)
+{
+ focus_order[d] = g_list_remove(focus_order[d], c);
+ if (!c->iconic) {
+ focus_order[d] = g_list_prepend(focus_order[d], c);
+ } else {
+ GList *it;
+
+ /* insert before first iconic window */
+ for (it = focus_order[d];
+ it && !((Client*)it->data)->iconic; it = it->next);
+ g_list_insert_before(focus_order[d], it, c);
+ }
+}
+
+void focus_order_to_top(Client *c)
+{
+ guint d, i;
+
+ d = c->desktop;
+ if (d == DESKTOP_ALL) {
+ for (i = 0; i < screen_num_desktops; ++i)
+ to_top(c, i);
+ } else
+ to_top(c, d);
+}
+
+static void to_bottom(Client *c, guint d)
+{
+ focus_order[d] = g_list_remove(focus_order[d], c);
+ if (c->iconic) {
+ focus_order[d] = g_list_append(focus_order[d], c);
+ } else {
+ GList *it;
+
+ /* insert before first iconic window */
+ for (it = focus_order[d];
+ it && !((Client*)it->data)->iconic; it = it->next);
+ g_list_insert_before(focus_order[d], it, c);
+ }
+}
+
+void focus_order_to_bottom(Client *c)
+{
+ guint d, i;
+
+ d = c->desktop;
+ if (d == DESKTOP_ALL) {
+ for (i = 0; i < screen_num_desktops; ++i)
+ to_bottom(c, i);
+ } else
+ to_bottom(c, d);
+}
struct Client *focus_cycle(gboolean forward, gboolean linear, gboolean done,
gboolean cancel);
+/*! Add a new client into the focus order */
+void focus_order_add_new(struct Client *c);
+
+/*! Remove a client from the focus order */
+void focus_order_remove(struct Client *c);
+
+/*! Move a client to the top of the focus order */
+void focus_order_to_top(struct Client *c);
+
+/*! Move a client to the bottom of the focus order (keeps iconic windows at the
+ very bottom always though). */
+void focus_order_to_bottom(struct Client *c);
+
#endif