summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2003-03-19 07:08:15 +0000
committerDana Jansens <danakj@orodu.net>2003-03-19 07:08:15 +0000
commit648c55b829e09c66222a9bbf08d10434622feae2 (patch)
tree7e6c2eb58a71e4691c9c5d85325b9d9000019138 /openbox
parent597fad9d8d5b7be27cabeeec750ed15f86377a07 (diff)
move the focus_order lists into the kernel
Diffstat (limited to 'openbox')
-rw-r--r--openbox/client.c28
-rw-r--r--openbox/dispatch.h7
-rw-r--r--openbox/focus.c29
-rw-r--r--openbox/focus.h5
-rw-r--r--openbox/openbox.c3
-rw-r--r--openbox/screen.c12
6 files changed, 76 insertions, 8 deletions
diff --git a/openbox/client.c b/openbox/client.c
index 790dba5a..dfc70348 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -214,6 +214,7 @@ void client_unmanage_all()
void client_unmanage(Client *client)
{
+ guint i;
int j;
GSList *it;
@@ -242,6 +243,15 @@ void client_unmanage(Client *client)
stacking_list = g_list_remove(stacking_list, client);
g_hash_table_remove(client_map, (gpointer)client->window);
+ /* update the focus lists */
+ if (client->desktop == DESKTOP_ALL) {
+ for (i = 0; i < screen_num_desktops; ++i)
+ focus_order[i] = g_list_remove(focus_order[i], client);
+ } else {
+ i = client->desktop;
+ focus_order[i] = g_list_remove(focus_order[i], client);
+ }
+
/* once the client is out of the list, update the struts to remove it's
influence */
screen_update_struts();
@@ -257,7 +267,7 @@ void client_unmanage(Client *client)
client_calc_layer(it->data);
}
- /* unfocus the client (calls the focus callbacks) (we're out of the
+ /* unfocus the client (dispatchs the focus event) (we're out of the
transient lists already, so being modal doesn't matter) */
if (client->focused)
client_unfocus(client);
@@ -1622,7 +1632,7 @@ void client_close(Client *self)
void client_set_desktop(Client *self, guint target)
{
- guint old;
+ guint old, i;
if (target == self->desktop) return;
@@ -1639,6 +1649,20 @@ void client_set_desktop(Client *self, guint target)
client_showhide(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)
+ focus_order[i] = g_list_prepend(focus_order[i], self);
+ } else {
+ focus_order[target] = g_list_prepend(focus_order[target], self);
+ }
+
dispatch_client(Event_Client_Desktop, self, target, old);
}
diff --git a/openbox/dispatch.h b/openbox/dispatch.h
index 5fa22e0c..a2838621 100644
--- a/openbox/dispatch.h
+++ b/openbox/dispatch.h
@@ -20,9 +20,10 @@ typedef enum {
Event_Client_New = 1 << 8, /* new window, before mapping */
Event_Client_Mapped = 1 << 9, /* new window, after mapping */
Event_Client_Destroy = 1 << 10, /* unmanaged */
- Event_Client_Focus = 1 << 11, /* focused */
- Event_Client_Unfocus = 1 << 12, /* unfocused */
- Event_Client_Urgent = 1 << 13, /* entered/left urgent state */
+ Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping */
+ Event_Client_Focus = 1 << 12, /* focused */
+ Event_Client_Unfocus = 1 << 13, /* unfocused */
+ Event_Client_Urgent = 1 << 14, /* entered/left urgent state */
Event_Client_Desktop = 1 << 15, /* moved to a new desktop */
Event_Ob_Desktop = 1 << 16, /* changed desktops */
diff --git a/openbox/focus.c b/openbox/focus.c
index cfc3485e..d09494bf 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -5,8 +5,10 @@
#include "dispatch.h"
#include <X11/Xlib.h>
+#include <glib.h>
Client *focus_client = NULL;
+GList **focus_order = NULL;
Window focus_backup = None;
@@ -14,6 +16,8 @@ void focus_set_client(Client *client);
void focus_startup()
{
+ guint i;
+
/* create the window which gets focus when no clients get it. Have to
make it override-redirect so we don't try manage it, since it is
mapped. */
@@ -25,14 +29,31 @@ void focus_startup()
CopyFromParent, CWOverrideRedirect, &attrib);
XMapRaised(ob_display, focus_backup);
+ focus_order = g_new(GList*, screen_num_desktops);
+ for (i = 0; i < screen_num_desktops; ++i)
+ focus_order[i] = NULL;
+
/* start with nothing focused */
focus_set_client(NULL);
}
+void focus_shutdown()
+{
+ guint i;
+
+ for (i = 0; i < screen_num_desktops; ++i)
+ g_list_free(focus_order[i]);
+ g_free(focus_order);
+
+ /* reset focus to root */
+ XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
+}
+
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);
@@ -47,6 +68,14 @@ void focus_set_client(Client *client)
old = focus_client;
focus_client = client;
+ /* move to the top of the list */
+ 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);
+ }
+
/* set the NET_ACTIVE_WINDOW hint */
active = client ? client->window : None;
PROP_SET32(ob_root, net_active_window, window, active);
diff --git a/openbox/focus.h b/openbox/focus.h
index 9db52026..cb9a9a99 100644
--- a/openbox/focus.h
+++ b/openbox/focus.h
@@ -2,6 +2,7 @@
#define __focus_h
#include <X11/Xlib.h>
+#include <glib.h>
struct Client;
@@ -11,7 +12,11 @@ extern Window focus_backup;
/*! The client which is currently focused */
extern struct Client *focus_client;
+/*! The recent focus order on each desktop */
+extern GList **focus_order;
+
void focus_startup();
+void focus_shutdown();
/*! Specify which client is currently focused, this doesn't actually
send focus anywhere, its called by the Focus event handlers */
diff --git a/openbox/openbox.c b/openbox/openbox.c
index c9d88279..9f90a9e0 100644
--- a/openbox/openbox.c
+++ b/openbox/openbox.c
@@ -160,6 +160,7 @@ int main(int argc, char **argv)
plugin_shutdown(); /* calls all the plugins' shutdown functions */
grab_shutdown();
client_shutdown();
+ focus_shutdown();
screen_shutdown();
event_shutdown();
engine_shutdown();
@@ -168,8 +169,6 @@ int main(int argc, char **argv)
timer_shutdown();
}
- /* reset focus to root before exiting */
- XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
XCloseDisplay(ob_display);
dispatch_shutdown();
diff --git a/openbox/screen.c b/openbox/screen.c
index 8f60029a..01acbfe2 100644
--- a/openbox/screen.c
+++ b/openbox/screen.c
@@ -195,7 +195,7 @@ void screen_resize()
void screen_set_num_desktops(guint num)
{
- guint old;
+ guint i, old;
gulong *viewport;
g_assert(num > 0);
@@ -237,6 +237,16 @@ void screen_set_num_desktops(guint num)
/* may be some unnamed desktops that we need to fill in with names */
screen_update_desktop_names();
+ /* update the focus lists */
+ /* free our lists for the desktops which have disappeared */
+ for (i = num; i < old; ++i)
+ g_list_free(focus_order[i]);
+ /* realloc the array */
+ focus_order = g_renew(GList*, focus_order, num);
+ /* set the new lists to be empty */
+ for (i = old; i < num; ++i)
+ focus_order[i] = NULL;
+
dispatch_ob(Event_Ob_NumDesktops, num, old);
/* change our desktop if we're on one that no longer exists! */