]> Dogcows Code - chaz/openbox/blob - plugins/focus.c
focus fallback works when nothing is focused
[chaz/openbox] / plugins / focus.c
1 #include "../kernel/dispatch.h"
2 #include "../kernel/screen.h"
3 #include "../kernel/client.h"
4 #include "../kernel/focus.h"
5 #include "../kernel/stacking.h"
6
7 static GSList **focus_order = NULL;
8
9 static void events(ObEvent *e, void *foo)
10 {
11 guint i;
12 guint new, old;
13 GSList *it;
14
15 switch (e->type) {
16 case Event_Client_Mapped:
17 /* focus new normal windows */
18 if (client_normal(e->data.c.client))
19 client_focus(e->data.c.client);
20 break;
21
22 case Event_Client_Destroy:
23 i = e->data.c.client->desktop;
24 focus_order[i] = g_slist_remove(focus_order[i], e->data.c.client);
25 break;
26
27 case Event_Ob_NumDesktops:
28 new = e->data.o.num[0];
29 old = e->data.o.num[1];
30 /* free our lists for the desktops which have disappeared */
31 for (i = new; i < old; ++i)
32 g_slist_free(focus_order[i]);
33 /* realloc the array */
34 focus_order = g_renew(GSList*, focus_order, new);
35 /* set the new lists to be empty */
36 for (i = old; i < new; ++i)
37 focus_order[i] = NULL;
38 break;
39
40 case Event_Client_Desktop:
41 old = e->data.c.num[1];
42 if (old != DESKTOP_ALL)
43 focus_order[old] = g_slist_remove(focus_order[old],
44 e->data.c.client);
45 else
46 for (i = 0; i < screen_num_desktops; ++i)
47 focus_order[i] = g_slist_remove(focus_order[i],
48 e->data.c.client);
49 break;
50
51 case Event_Ob_Desktop:
52 /* focus the next available target */
53 new = e->data.o.num[0];
54 for (it = focus_order[new]; it != NULL; it = it->next)
55 if (client_focus(it->data))
56 break;
57 break;
58
59 case Event_Client_Unfocus:
60 if (focus_client == NULL) { /* nothing is left with focus! */
61 /* focus the next available target */
62 for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
63 if (client_focus(it->data))
64 break;
65 }
66 break;
67
68 case Event_Client_Focus:
69 /* move to the top of the list */
70 focus_order[e->data.c.num[1]] =
71 g_slist_remove(focus_order[e->data.c.num[1]], e->data.c.client);
72 focus_order[e->data.c.num[1]] =
73 g_slist_prepend(focus_order[e->data.c.num[1]], e->data.c.client);
74 break;
75
76 default:
77 g_assert_not_reached();
78 }
79 }
80
81 void plugin_startup()
82 {
83 guint i;
84
85 dispatch_register(Event_Client_Mapped | Event_Client_Destroy |
86 Event_Ob_Desktop | Event_Ob_NumDesktops |
87 Event_Client_Focus | Event_Client_Unfocus |
88 Event_Client_Desktop,
89 (EventHandler)events, NULL);
90
91 focus_order = g_new(GSList*, screen_num_desktops);
92 for (i = 0; i < screen_num_desktops; ++i)
93 focus_order[i] = NULL;
94 }
95
96 void plugin_shutdown()
97 {
98 guint i;
99
100 dispatch_register(0, (EventHandler)events, NULL);
101
102 for (i = 0; i < screen_num_desktops; ++i)
103 g_slist_free(focus_order[i]);
104 g_free(focus_order);
105 }
This page took 0.038448 seconds and 5 git commands to generate.