summaryrefslogtreecommitdiff
path: root/openbox/focus.c
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-04-07 03:46:41 +0000
committerDana Jansens <danakj@orodu.net>2003-04-07 03:46:41 +0000
commitdb086ef336e01ee23c777f3dc6678568565d44ef (patch)
tree2cc04723f59aff38de8065eb92d1bcab1d33b5f8 /openbox/focus.c
parent1f775fdd864715abb622070a9b4dd38341d6da79 (diff)
put focus_cycle into focus.c, use it there in the action. improved it as well to handle odd cases like modal windows. added functions to client.c which are needed by the focus cycling routine.
Diffstat (limited to 'openbox/focus.c')
-rw-r--r--openbox/focus.c81
1 files changed, 70 insertions, 11 deletions
diff --git a/openbox/focus.c b/openbox/focus.c
index 4ff85c5d..ed2c79d6 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -7,6 +7,7 @@
#include "dispatch.h"
#include "focus.h"
#include "parse.h"
+#include "engine.h"
#include <X11/Xlib.h>
#include <glib.h>
@@ -18,7 +19,8 @@ GList **focus_order = NULL; /* these lists are created when screen_startup
Window focus_backup = None;
gboolean focus_new = TRUE;
gboolean focus_follow = TRUE;
-int focus_ignore_in = 0;
+
+static gboolean noreorder = 0;
static void parse_assign(char *name, ParseToken *value)
{
@@ -79,11 +81,21 @@ void focus_shutdown()
event_lasttime);
}
+static void push_to_top(Client *client)
+{
+ guint desktop;
+
+ desktop = client->desktop;
+ if (desktop == DESKTOP_ALL) desktop = screen_desktop;
+ focus_order[desktop] = g_list_remove(focus_order[desktop], client);
+ focus_order[desktop] = g_list_prepend(focus_order[desktop], client);
+ g_message("REORDERING");
+}
+
void focus_set_client(Client *client)
{
Window active;
Client *old;
- guint desktop;
/* uninstall the old colormap, and install the new one */
screen_install_colormap(focus_client, FALSE);
@@ -100,15 +112,10 @@ void focus_set_client(Client *client)
focus_client = client;
/* move to the top of the list */
- if (focus_ignore_in) {
- g_assert(focus_ignore_in > 0);
- --focus_ignore_in;
- } else if (client != NULL) {
- desktop = client->desktop;
- if (desktop == DESKTOP_ALL) desktop = screen_desktop;
- focus_order[desktop] = g_list_remove(focus_order[desktop], client);
- focus_order[desktop] = g_list_prepend(focus_order[desktop], client);
- }
+ if (noreorder)
+ --noreorder;
+ else if (client != NULL)
+ push_to_top(client);
/* set the NET_ACTIVE_WINDOW hint */
active = client ? client->window : None;
@@ -171,3 +178,55 @@ void focus_fallback(gboolean switching_desks)
focus_set_client(NULL);
}
}
+
+void focus_cycle(gboolean forward, gboolean linear, gboolean done,
+ gboolean cancel)
+{
+ static Client *first = NULL;
+ static Client *t = NULL;
+ static GList *order = NULL;
+ GList *it, *start, *list;
+ Client *ft;
+
+ if (cancel) {
+ if (first) client_focus(first);
+ goto done_cycle;
+ } else if (done) {
+ if (focus_client) {
+ push_to_top(focus_client); /* move to top of focus_order */
+ stacking_raise(focus_client);
+ }
+ goto done_cycle;
+ }
+ if (!first) first = focus_client;
+
+ if (linear) list = client_list;
+ else list = focus_order[screen_desktop];
+
+ start = it = g_list_find(list, focus_client);
+ if (!start) goto done_cycle; /* switched desktops or something? */
+
+ do {
+ if (forward) {
+ it = it->next;
+ if (it == NULL) it = list;
+ } else {
+ it = it->prev;
+ if (it == NULL) it = g_list_last(list);
+ }
+ ft = client_focus_target(it->data);
+ if (ft == it->data && focus_client != ft && client_focusable(ft)) {
+ if (client_focus(ft)) {
+ noreorder++; /* avoid reordering the focus_order */
+ break;
+ }
+ }
+ } while (it != start);
+ return;
+
+done_cycle:
+ t = NULL;
+ first = NULL;
+ g_list_free(order);
+ order = NULL;
+}