all repos — openbox @ 58cfbb7f8419e084af6b6b8b00c88ed270c29e88

openbox fork - make it a bit more like ryudo

Clients Menus and Slits are all 'ObWindow's now.
Stacking is done with ObWindows.
Slits add themselves to the stacking order, as do clients of course.
Added some macros for adding/removing to the stacking order.
Dana Jansens danakj@orodu.net
commit

58cfbb7f8419e084af6b6b8b00c88ed270c29e88

parent

506122a110035f810c7d25225661973845a59c62

M openbox/Makefile.amopenbox/Makefile.am

@@ -26,13 +26,13 @@ openbox3_SOURCES=parse.tab.c parse.lex.c action.c client.c config.c \

extensions.c focus.c frame.c grab.c menu.c menu_render.c \ openbox.c framerender.c parse.c plugin.c prop.c screen.c \ stacking.c dispatch.c event.c group.c timer.c xerror.c \ - moveresize.c startup.c popup.c slit.c + moveresize.c startup.c popup.c slit.c window.c noinst_HEADERS=action.h client.h config.h dispatch.h event.h extensions.h \ focus.h frame.h framerender.h geom.h gettext.h grab.h group.h \ menu.h openbox.h parse.h parse.tab.h plugin.h prop.h screen.h \ stacking.h timer.h xerror.h moveresize.h startup.h popup.h \ - slit.h + slit.h window.h # kill the implicit .c.y rule %.c: %.y
M openbox/action.copenbox/action.c

@@ -222,14 +222,14 @@ void action_focusraise(union ActionData *data)

{ if (data->client.c) { client_focus(data->client.c); - stacking_raise(data->client.c); + stacking_raise(CLIENT_AS_WINDOW(data->client.c)); } } void action_raise(union ActionData *data) { if (data->client.c) - stacking_raise(data->client.c); + stacking_raise(CLIENT_AS_WINDOW(data->client.c)); } void action_unshaderaise(union ActionData *data)

@@ -238,7 +238,7 @@ if (data->client.c) {

if (data->client.c->shaded) client_shade(data->client.c, FALSE); else - stacking_raise(data->client.c); + stacking_raise(CLIENT_AS_WINDOW(data->client.c)); } }

@@ -246,7 +246,7 @@ void action_shadelower(union ActionData *data)

{ if (data->client.c) { if (data->client.c->shaded) - stacking_lower(data->client.c); + stacking_lower(CLIENT_AS_WINDOW(data->client.c)); else client_shade(data->client.c, TRUE); }

@@ -255,7 +255,7 @@

void action_lower(union ActionData *data) { if (data->client.c) - stacking_lower(data->client.c); + stacking_lower(CLIENT_AS_WINDOW(data->client.c)); } void action_close(union ActionData *data)
M openbox/client.copenbox/client.c

@@ -158,7 +158,7 @@ Client *c;

w = startup_stack_order[i-1]; c = g_hash_table_lookup(client_map, &w); - if (c) stacking_lower(c); + if (c) stacking_lower(CLIENT_AS_WINDOW(c)); } g_free(startup_stack_order); startup_stack_order = NULL;

@@ -222,6 +222,7 @@

/* create the Client struct, and populate it from the hints on the window */ self = g_new(Client, 1); + self->obwin.type = Window_Client; self->window = window; client_get_all(self);

@@ -242,14 +243,14 @@

grab_server(FALSE); client_list = g_list_append(client_list, self); - stacking_list = g_list_append(stacking_list, self); + stacking_add(self); g_assert(!g_hash_table_lookup(client_map, &self->window)); g_hash_table_insert(client_map, &self->window, self); /* update the focus lists */ focus_order_add_new(self); - stacking_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); screen_update_struts();

@@ -336,7 +337,7 @@

frame_hide(self->frame); client_list = g_list_remove(client_list, self); - stacking_list = g_list_remove(stacking_list, self); + stacking_remove(self); g_hash_table_remove(client_map, &self->window); /* update the focus lists */

@@ -1455,8 +1456,7 @@ static StackLayer calc_layer(Client *self)

{ StackLayer l; - if (self->iconic) l = Layer_Icon; - else if (self->fullscreen) l = Layer_Fullscreen; + if (self->fullscreen) l = Layer_Fullscreen; else if (self->type == Type_Desktop) l = Layer_Desktop; else if (self->type == Type_Dock) { if (!self->below) l = Layer_Top;

@@ -1484,7 +1484,7 @@ calc_recursive(it->data, orig, l, raised ? raised : l != old);

if (!raised && l != old) if (orig->frame) /* only restack if the original window is managed */ - stacking_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); } void client_calc_layer(Client *self)

@@ -2028,7 +2028,7 @@ if (!donthide)

client_showhide(self); /* raise if it was not already on the desktop */ if (old != DESKTOP_ALL) - stacking_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); screen_update_struts(); /* add to the new desktop(s) */

@@ -2310,7 +2310,7 @@ return;

if (self->shaded) client_shade(self, FALSE); client_focus(self); - stacking_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); } gboolean client_focused(Client *self)
M openbox/client.hopenbox/client.h

@@ -110,6 +110,8 @@ } Decoration;

typedef struct Client { + ObWindow obwin; + Window window; /*! The window's decorations. NULL while the window is being managed! */
M openbox/config.hopenbox/config.h

@@ -13,6 +13,8 @@ /*! Focus the last focused window as a fallback when switching desktops */

extern gboolean config_focus_last_on_desktop; /*! Show a popup dialog while cycling focus */ extern gboolean config_focus_popup; +/*! The number of slits to create */ +extern int config_slit_number; /* The name of the theme */ char *config_theme;
M openbox/event.copenbox/event.c

@@ -916,6 +916,8 @@

static void event_handle_slit(Slit *s, XEvent *e) { switch (e->type) { + case ButtonPress: + stacking_raise(SLIT_AS_WINDOW(s)); case EnterNotify: slit_hide(s, FALSE); break;
M openbox/focus.copenbox/focus.c

@@ -40,8 +40,7 @@ focus_backup = XCreateWindow(ob_display, ob_root,

-100, -100, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect, &attrib); - XMapWindow(ob_display, focus_backup); - stacking_raise_internal(focus_backup); + XMapRaised(ob_display, focus_backup); /* start with nothing focused */ focus_set_client(NULL);
M openbox/menu.copenbox/menu.c

@@ -154,6 +154,7 @@ XSetWindowAttributes attrib;

Menu *self; self = g_new0(Menu, 1); + self->obwin.type = Window_Menu; self->label = g_strdup(label); self->name = g_strdup(name); self->parent = parent;

@@ -350,7 +351,9 @@ MIN(x, screen_physical_size.width - self->size.width),

MIN(y, screen_physical_size.height - self->size.height)); if (!self->shown) { - stacking_raise_internal(self->frame); + /* XXX gotta add to the stacking list first! + stacking_raise(MENU_AS_WINDOW(self)); + */ XMapWindow(ob_display, self->frame); self->shown = TRUE; } else if (self->shown && self->open_submenu) {
M openbox/menu.hopenbox/menu.h

@@ -18,6 +18,8 @@ typedef void(*menu_controller_mouseover)(struct MenuEntry *self,

gboolean enter); typedef struct Menu { + ObWindow obwin; + char *label; char *name;
M openbox/openbox.copenbox/openbox.c

@@ -186,7 +186,6 @@ if (!theme) return 1;

menu_startup(); frame_startup(); - stacking_startup(); moveresize_startup(); focus_startup(); screen_startup();

@@ -215,7 +214,6 @@ group_shutdown();

screen_shutdown(); focus_shutdown(); moveresize_shutdown(); - stacking_shutdown(); frame_shutdown(); menu_shutdown(); grab_shutdown();
M openbox/slit.copenbox/slit.c

@@ -1,38 +1,13 @@

#include "slit.h" #include "screen.h" #include "grab.h" -#include "timer.h" #include "openbox.h" #include "render/theme.h" -#include "render/render.h" #define SLIT_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \ EnterWindowMask | LeaveWindowMask) #define SLITAPP_EVENT_MASK (StructureNotifyMask) -struct Slit { - Window frame; - - /* user-requested position stuff */ - SlitPosition pos; - int gravity; - int user_x, user_y; - - /* actual position (when not auto-hidden) */ - int x, y; - int w, h; - - gboolean horz; - gboolean hide; - gboolean hidden; - - Appearance *a_frame; - - Timer *hide_timer; - - GList *slit_apps; -}; - GHashTable *slit_map = NULL; GHashTable *slit_app_map = NULL;

@@ -53,12 +28,14 @@ slit_app_map = g_hash_table_new(g_int_hash, g_int_equal);

nslits = 1; slit = g_new0(struct Slit, nslits); + slit->obwin.type = Window_Slit; for (i = 0; i < nslits; ++i) { slit[i].horz = FALSE; slit[i].hide = FALSE; slit[i].hidden = TRUE; slit[i].pos = SlitPos_TopRight; + slit[i].layer = Layer_Top; attrib.event_mask = SLIT_EVENT_MASK; attrib.override_redirect = True;

@@ -71,6 +48,8 @@ XSetWindowBorder(ob_display, slit[i].frame, theme_b_color->pixel);

XSetWindowBorderWidth(ob_display, slit[i].frame, theme_bwidth); g_hash_table_insert(slit_map, &slit[i].frame, &slit[i]); + stacking_add(&slit[i]); + stacking_raise(SLIT_AS_WINDOW(&slit[i])); } }

@@ -82,6 +61,7 @@ for (i = 0; i < nslits; ++i) {

XDestroyWindow(ob_display, slit[i].frame); appearance_free(slit[i].a_frame); g_hash_table_remove(slit_map, &slit[i].frame); + stacking_remove(&slit[i]); } g_hash_table_destroy(slit_app_map); g_hash_table_destroy(slit_map);
M openbox/slit.hopenbox/slit.h

@@ -1,11 +1,52 @@

#ifndef __slit_h #define __slit_h +#include "timer.h" +#include "render/render.h" +#include "window.h" +#include "stacking.h" + #include <glib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> -typedef struct Slit Slit; +typedef enum { + SlitPos_Floating, + SlitPos_TopLeft, + SlitPos_Top, + SlitPos_TopRight, + SlitPos_Right, + SlitPos_BottomRight, + SlitPos_Bottom, + SlitPos_BottomLeft, + SlitPos_Left +} SlitPosition; + +typedef struct Slit { + ObWindow obwin; + + Window frame; + StackLayer layer; + + /* user-requested position stuff */ + SlitPosition pos; + int gravity; + int user_x, user_y; + + /* actual position (when not auto-hidden) */ + int x, y; + int w, h; + + gboolean horz; + gboolean hide; + gboolean hidden; + + Appearance *a_frame; + + Timer *hide_timer; + + GList *slit_apps; +} Slit; typedef struct SlitApp { int ignore_unmaps;

@@ -18,18 +59,6 @@ int y;

int w; int h; } SlitApp; - -typedef enum { - SlitPos_Floating, - SlitPos_TopLeft, - SlitPos_Top, - SlitPos_TopRight, - SlitPos_Right, - SlitPos_BottomRight, - SlitPos_Bottom, - SlitPos_BottomLeft, - SlitPos_Left -} SlitPosition; extern GHashTable *slit_map; extern GHashTable *slit_app_map;
M openbox/stacking.copenbox/stacking.c

@@ -4,28 +4,11 @@ #include "focus.h"

#include "client.h" #include "group.h" #include "frame.h" +#include "window.h" #include <glib.h> GList *stacking_list = NULL; -static Window top_window = None; - -void stacking_startup() -{ - XSetWindowAttributes attrib; - attrib.override_redirect = TRUE; - top_window = XCreateWindow(ob_display, ob_root, - -100, -100, 1, 1, 0, - CopyFromParent, InputOutput, CopyFromParent, - CWOverrideRedirect, &attrib); - XMapWindow(ob_display, top_window); -} - -void stacking_shutdown() -{ - XDestroyWindow(ob_display, top_window); -} - void stacking_set_list() { Window *windows, *win_it;

@@ -44,7 +27,8 @@ windows = g_new(Window, size);

win_it = windows; for (it = g_list_last(stacking_list); it != NULL; it = it->prev, ++win_it) - *win_it = ((Client*)it->data)->window; + if (WINDOW_IS_CLIENT(it->data)) + *win_it = window_top(it->data); } else windows = NULL;

@@ -67,7 +51,7 @@ return it;

return NULL; } -static void raise_recursive(Client *client) +static void raise_recursive(ObWindow *window) { Window wins[2]; /* only ever restack 2 windows. */ GList *it, *low;

@@ -75,21 +59,27 @@ GSList *sit;

g_assert(stacking_list != NULL); /* this would be bad */ - /* remove the client before looking so we can't run into ourselves and our + /* remove the window before looking so we can't run into ourselves and our transients can't either. */ - stacking_list = g_list_remove(stacking_list, client); + stacking_list = g_list_remove(stacking_list, window); /* raise transients first */ - for (sit = client->transients; sit; sit = sit->next) - raise_recursive(sit->data); + if (WINDOW_IS_CLIENT(window)) { + Client *client = WINDOW_AS_CLIENT(window); + for (sit = client->transients; sit; sit = sit->next) + raise_recursive(sit->data); + } /* find 'it' where it is the positiion in the stacking order where - 'client' will be inserted *before* */ + 'window' will be inserted *before* */ - low = find_lowest_transient(client); + if (WINDOW_IS_CLIENT(window)) + low = find_lowest_transient(WINDOW_AS_CLIENT(window)); + else + low = NULL; /* the stacking list is from highest to lowest */ for (it = g_list_last(stacking_list); it; it = it->prev) { - if (it == low || client->layer < ((Client*)it->data)->layer) { + if (it == low || window_layer(window) < window_layer(it->data)) { it = it->next; break; }

@@ -104,110 +94,112 @@ */

if (it == stacking_list) wins[0] = focus_backup; else if (it != NULL) - wins[0] = ((Client*)it->prev->data)->frame->window; + wins[0] = window_top(it->prev->data); else - wins[0] = ((Client*)g_list_last(stacking_list)->data)->frame->window; - wins[1] = client->frame->window; + wins[0] = window_top(g_list_last(stacking_list)->data); + wins[1] = window_top(window); - stacking_list = g_list_insert_before(stacking_list, it, client); + stacking_list = g_list_insert_before(stacking_list, it, window); XRestackWindows(ob_display, wins, 2); } -void stacking_raise(Client *client) +void stacking_raise(ObWindow *window) { g_assert(stacking_list != NULL); /* this would be bad */ - /* move up the transient chain as far as possible first */ - while (client->transient_for) { - if (client->transient_for != TRAN_GROUP) { - client = client->transient_for; - } else { - GSList *it; + if (WINDOW_IS_CLIENT(window)) { + Client *client = WINDOW_AS_CLIENT(window); + /* move up the transient chain as far as possible first */ + while (client->transient_for) { + if (client->transient_for != TRAN_GROUP) { + client = client->transient_for; + } else { + GSList *it; - /* the check for TRAN_GROUP is to prevent an infinate loop with - 2 transients of the same group at the head of the group's - members list */ - for (it = client->group->members; it; it = it->next) { - Client *c = it->data; + /* the check for TRAN_GROUP is to prevent an infinate loop with + 2 transients of the same group at the head of the group's + members list */ + for (it = client->group->members; it; it = it->next) { + Client *c = it->data; - if (c != client && c->transient_for != TRAN_GROUP) { - client = it->data; - break; + if (c != client && c->transient_for != TRAN_GROUP) { + client = it->data; + break; + } } + if (it == NULL) break; } - if (it == NULL) break; } + window = CLIENT_AS_WINDOW(client); } - raise_recursive(client); + raise_recursive(window); stacking_set_list(); } -static void lower_recursive(Client *client, Client *above) +static void lower_recursive(ObWindow *window, ObWindow *above) { Window wins[2]; /* only ever restack 2 windows. */ GList *it; GSList *sit; /* find 'it' where 'it' is the position in the stacking_list where the - 'client' will be placed *after* */ + 'window' will be placed *after* */ for (it = g_list_last(stacking_list); it != stacking_list; it = it->prev) - if (client->layer <= ((Client*)it->data)->layer && it->data != above) + if (window_layer(window) <= window_layer(it->data) && + it->data != above) break; - if (it->data != client) { /* not already the bottom */ - wins[0] = ((Client*)it->data)->frame->window; - wins[1] = client->frame->window; + if (it->data != window) { /* not already the bottom */ + wins[0] = window_top(it->data); + wins[1] = window_top(window); - stacking_list = g_list_remove(stacking_list, client); - stacking_list = g_list_insert_before(stacking_list, it->next, client); + stacking_list = g_list_remove(stacking_list, window); + stacking_list = g_list_insert_before(stacking_list, it->next, window); XRestackWindows(ob_display, wins, 2); } - for (sit = client->transients; sit; sit = sit->next) - lower_recursive(sit->data, client); + if (WINDOW_IS_CLIENT(window)) { + Client *client = WINDOW_AS_CLIENT(window); + for (sit = client->transients; sit; sit = sit->next) + lower_recursive(CLIENT_AS_WINDOW(sit->data), window); + } } -void stacking_lower(Client *client) +void stacking_lower(ObWindow *window) { g_assert(stacking_list != NULL); /* this would be bad */ - /* move up the transient chain as far as possible first */ - while (client->transient_for) { - if (client->transient_for != TRAN_GROUP) { - client = client->transient_for; - } else { - GSList *it; + if (WINDOW_IS_CLIENT(window)) { + Client *client = WINDOW_AS_CLIENT(window); + /* move up the transient chain as far as possible first */ + while (client->transient_for) { + if (client->transient_for != TRAN_GROUP) { + client = client->transient_for; + } else { + GSList *it; - /* the check for TRAN_GROUP is to prevent an infinate loop with - 2 transients of the same group at the head of the group's - members list */ - for (it = client->group->members; it; it = it->next) { - Client *c = it->data; + /* the check for TRAN_GROUP is to prevent an infinate loop with + 2 transients of the same group at the head of the group's + members list */ + for (it = client->group->members; it; it = it->next) { + Client *c = it->data; - if (c != client && c->transient_for != TRAN_GROUP) { - client = it->data; - break; + if (c != client && c->transient_for != TRAN_GROUP) { + client = it->data; + break; + } } + if (it == NULL) break; } - if (it == NULL) break; } + window = CLIENT_AS_WINDOW(client); } - lower_recursive(client, NULL); + lower_recursive(window, NULL); stacking_set_list(); } - -void stacking_raise_internal(Window win) -{ - Window wins[2]; /* only ever restack 2 windows. */ - - wins[0] = top_window; - wins[1] = win; - - XRestackWindows(ob_display, wins, 2); -}
M openbox/stacking.hopenbox/stacking.h

@@ -1,46 +1,42 @@

#ifndef __stacking_h #define __stacking_h +#include "window.h" + #include <glib.h> #include <X11/Xlib.h> -struct Client; - /*! The possible stacking layers a client window can be a part of */ typedef enum { - Layer_Icon, /*!< 0 - iconified windows, in any order at all */ - Layer_Desktop, /*!< 1 - desktop windows */ - Layer_Below, /*!< 2 - normal windows w/ below */ - Layer_Normal, /*!< 3 - normal windows */ - Layer_Above, /*!< 4 - normal windows w/ above */ - Layer_Top, /*!< 5 - always-on-top-windows (docks?) */ - Layer_Fullscreen, /*!< 6 - fullscreeen windows */ - Layer_Internal /*!< 7 - openbox windows/menus */ + Layer_Desktop, /*!< 0 - desktop windows */ + Layer_Below, /*!< 1 - normal windows w/ below */ + Layer_Normal, /*!< 2 - normal windows */ + Layer_Above, /*!< 3 - normal windows w/ above */ + Layer_Top, /*!< 4 - always-on-top-windows (docks?) */ + Layer_Fullscreen, /*!< 5 - fullscreeen windows */ + Layer_Internal /*!< 6 - openbox windows/menus */ } StackLayer; -/* list of Client*s in stacking order from highest to lowest */ +/* list of ObWindow*s in stacking order from highest to lowest */ extern GList *stacking_list; -void stacking_startup(); -void stacking_shutdown(); +/*! Sets the window stacking list on the root window from the + stacking_list */ +void stacking_set_list(); -/*! Sets the client stacking list on the root window from the - stacking_clientlist */ -void stacking_set_list(); +#define stacking_add(win) stacking_list = g_list_append(stacking_list, win); +#define stacking_remove(win) stacking_list = g_list_remove(stacking_list, win); -/*! Raises a client window above all others in its stacking layer +/*! Raises a window above all others in its stacking layer raiseWindow has a couple of constraints that lowerWindow does not.<br> - 1) raiseWindow can be called after changing a Client's stack layer, and + 1) raiseWindow can be called after changing a Window's stack layer, and the list will be reorganized properly.<br> 2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be - called for the specified client. + called for the specified window. */ -void stacking_raise(struct Client *client); +void stacking_raise(ObWindow *window); /*! Lowers a client window below all others in its stacking layer */ -void stacking_lower(struct Client *client); - -/*! Raises an internal window (e.g. menus) */ -void stacking_raise_internal(Window win); +void stacking_lower(ObWindow *window); #endif
A openbox/window.c

@@ -0,0 +1,33 @@

+#include "window.h" +#include "menu.h" +#include "slit.h" +#include "client.h" +#include "frame.h" + +Window window_top(ObWindow *self) +{ + switch (self->type) { + case Window_Menu: + return ((Menu*)self)->frame; + case Window_Slit: + return ((Slit*)self)->frame; + case Window_Client: + return ((Client*)self)->frame->window; + } + g_assert_not_reached(); + return None; +} + +Window window_layer(ObWindow *self) +{ + switch (self->type) { + case Window_Menu: + return Layer_Internal; + case Window_Slit: + return ((Slit*)self)->layer; + case Window_Client: + return ((Client*)self)->layer; + } + g_assert_not_reached(); + return None; +}
A openbox/window.h

@@ -0,0 +1,35 @@

+#ifndef __window_h +#define __window_h + +#include <X11/Xlib.h> + +typedef enum { + Window_Menu, + Window_Slit, + Window_Client +} Window_InternalType; + +typedef struct ObWindow { + Window_InternalType type; +} ObWindow; + +#define WINDOW_IS_MENU(win) (((ObWindow*)win)->type == Window_Menu) +#define WINDOW_IS_SLIT(win) (((ObWindow*)win)->type == Window_Slit) +#define WINDOW_IS_CLIENT(win) (((ObWindow*)win)->type == Window_Client) + +struct Menu; +struct Slit; +struct Client; + +#define WINDOW_AS_MENU(win) ((struct Menu*)win) +#define WINDOW_AS_SLIT(win) ((struct Slit*)win) +#define WINDOW_AS_CLIENT(win) ((struct Client*)win) + +#define MENU_AS_WINDOW(menu) ((ObWindow*)menu) +#define SLIT_AS_WINDOW(slit) ((ObWindow*)slit) +#define CLIENT_AS_WINDOW(client) ((ObWindow*)client) + +Window window_top(ObWindow *self); +Window window_layer(ObWindow *self); + +#endif
M plugins/resistance.cplugins/resistance.c

@@ -65,6 +65,8 @@ for (it = stacking_list; it != NULL; it = it->next) {

Client *target; int tl, tt, tr, tb; /* 1 past the target's edges on each side */ + if (!WINDOW_IS_CLIENT(it->data)) + continue; target = it->data; /* don't snap to self or non-visibles */ if (!target->frame->visible || target == c) continue;