all repos — openbox @ 77bd01662820449ea9c958894fdba13ae3761d37

openbox fork - make it a bit more like ryudo

plugins/focus.c (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "../kernel/dispatch.h"
#include "../kernel/screen.h"
#include "../kernel/client.h"
#include "../kernel/stacking.h"

static GSList **focus_order = NULL;

static void events(ObEvent *e, void *foo)
{
    guint i;
    guint new, old;
    GSList *it;

    switch (e->type) {
    case Event_Client_Mapped:
        /* focus new normal windows */
        if (client_normal(e->data.c.client))
            client_focus(e->data.c.client);
        break;

    case Event_Ob_NumDesktops:
        new = e->data.o.num[0];
        old = e->data.o.num[1];
        /* free our lists for the desktops which have disappeared */
        for (i = new; i < old; ++i)
            g_slist_free(focus_order[i]);
        /* realloc the array */
        focus_order = g_renew(GSList*, focus_order, new);
        /* set the new lists to be empty */
        for (i = old; i < new; ++i)
            focus_order[i] = NULL;
        break;

    case Event_Client_Desktop:
        old = e->data.c.num[1];
        if (old != DESKTOP_ALL)
            focus_order[old] = g_slist_remove(focus_order[old],
                                              e->data.c.client);
        else
            for (i = 0; i < screen_num_desktops; ++i)
                focus_order[i] = g_slist_remove(focus_order[i],
                                                e->data.c.client);
        break;

    case Event_Ob_Desktop:
        for (it = focus_order[e->data.o.num[0]]; it != NULL; it = it->next)
            if (client_focus(it->data))
                break;
        break;

    case Event_Client_Focus:
        /* move to the top of the list */
        focus_order[e->data.c.num[1]] =
        g_slist_remove(focus_order[e->data.c.num[1]], e->data.c.client);
        focus_order[e->data.c.num[1]] =
        g_slist_prepend(focus_order[e->data.c.num[1]], e->data.c.client);
        break;

    default:
        g_assert_not_reached();
    }
}

void plugin_startup()
{
    guint i;

    dispatch_register(Event_Client_Mapped | Event_Ob_Desktop |
                      Event_Ob_NumDesktops | Event_Client_Focus |
                      Event_Client_Desktop, (EventHandler)events, NULL);

    focus_order = g_new(GSList*, screen_num_desktops);
    for (i = 0; i < screen_num_desktops; ++i)
        focus_order[i] = NULL;
}

void plugin_shutdown()
{
    guint i;

    dispatch_register(0, (EventHandler)events, NULL);

    for (i = 0; i < screen_num_desktops; ++i)
        g_slist_free(focus_order[i]);
    g_free(focus_order);
}