From 58cfbb7f8419e084af6b6b8b00c88ed270c29e88 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 11 May 2003 19:44:33 +0000 Subject: [PATCH] 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. --- openbox/Makefile.am | 4 +- openbox/action.c | 10 +-- openbox/client.c | 18 ++--- openbox/client.h | 2 + openbox/config.h | 2 + openbox/event.c | 2 + openbox/focus.c | 3 +- openbox/menu.c | 5 +- openbox/menu.h | 2 + openbox/openbox.c | 2 - openbox/slit.c | 30 ++------ openbox/slit.h | 55 ++++++++++---- openbox/stacking.c | 170 +++++++++++++++++++++---------------------- openbox/stacking.h | 44 +++++------ openbox/window.c | 33 +++++++++ openbox/window.h | 35 +++++++++ plugins/resistance.c | 2 + 17 files changed, 247 insertions(+), 172 deletions(-) create mode 100644 openbox/window.c create mode 100644 openbox/window.h diff --git a/openbox/Makefile.am b/openbox/Makefile.am index e860580e..f33b65d2 100644 --- a/openbox/Makefile.am +++ b/openbox/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 diff --git a/openbox/action.c b/openbox/action.c index ec5230e4..6206ccf4 100644 --- a/openbox/action.c +++ b/openbox/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 @@ void action_unshaderaise(union ActionData *data) 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_shadelower(union ActionData *data) 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) diff --git a/openbox/client.c b/openbox/client.c index 3389fdc6..6cd8454b 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -158,7 +158,7 @@ void client_manage_all() 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 @@ void client_manage(Window window) /* 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 @@ void client_manage(Window window) 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 @@ void client_unmanage(Client *self) 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 @@ static void calc_recursive(Client *self, Client *orig, StackLayer l, 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 @@ void client_set_desktop(Client *self, guint target, gboolean 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 @@ void client_activate(Client *self) if (self->shaded) client_shade(self, FALSE); client_focus(self); - stacking_raise(self); + stacking_raise(CLIENT_AS_WINDOW(self)); } gboolean client_focused(Client *self) diff --git a/openbox/client.h b/openbox/client.h index 9fe9c9d3..4461377d 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -110,6 +110,8 @@ typedef enum { typedef struct Client { + ObWindow obwin; + Window window; /*! The window's decorations. NULL while the window is being managed! */ diff --git a/openbox/config.h b/openbox/config.h index 081561cb..49e7c44e 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -13,6 +13,8 @@ extern gboolean config_focus_last; 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; diff --git a/openbox/event.c b/openbox/event.c index f6090f67..766be8fd 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -916,6 +916,8 @@ static void event_handle_menu(Menu *menu, XEvent *e) 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; diff --git a/openbox/focus.c b/openbox/focus.c index 2ee2cf2f..08fb09e1 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -40,8 +40,7 @@ void focus_startup() -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); diff --git a/openbox/menu.c b/openbox/menu.c index 7d63b545..7af380db 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -154,6 +154,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, 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 @@ void menu_control_show(Menu *self, int x, int y, Client *client) { 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) { diff --git a/openbox/menu.h b/openbox/menu.h index 43ac054f..c6b36719 100644 --- a/openbox/menu.h +++ b/openbox/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; diff --git a/openbox/openbox.c b/openbox/openbox.c index 47923966..505dffbc 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -186,7 +186,6 @@ int main(int argc, char **argv) menu_startup(); frame_startup(); - stacking_startup(); moveresize_startup(); focus_startup(); screen_startup(); @@ -215,7 +214,6 @@ int main(int argc, char **argv) screen_shutdown(); focus_shutdown(); moveresize_shutdown(); - stacking_shutdown(); frame_shutdown(); menu_shutdown(); grab_shutdown(); diff --git a/openbox/slit.c b/openbox/slit.c index 3956e0ec..311cd6ac 100644 --- a/openbox/slit.c +++ b/openbox/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 @@ void slit_startup() 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 @@ void slit_startup() 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 @@ void slit_shutdown() 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); diff --git a/openbox/slit.h b/openbox/slit.h index 3dd3d3db..3cdcb309 100644 --- a/openbox/slit.h +++ b/openbox/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 #include #include -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; @@ -19,18 +60,6 @@ typedef struct SlitApp { 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; diff --git a/openbox/stacking.c b/openbox/stacking.c index ab1e1955..782a57dd 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -4,28 +4,11 @@ #include "client.h" #include "group.h" #include "frame.h" +#include "window.h" #include 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 @@ void stacking_set_list() 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 @@ static GList *find_lowest_transient(Client *c) 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 @@ static void raise_recursive(Client *client) 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 @@ static void raise_recursive(Client *client) 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; - - /* 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 (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; + + 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; - - /* 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 (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; + + 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); -} diff --git a/openbox/stacking.h b/openbox/stacking.h index 22abb960..118cc5c3 100644 --- a/openbox/stacking.h +++ b/openbox/stacking.h @@ -1,46 +1,42 @@ #ifndef __stacking_h #define __stacking_h +#include "window.h" + #include #include -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 client stacking list on the root window from the - stacking_clientlist */ +/*! Sets the window stacking list on the root window from the + stacking_list */ void stacking_set_list(); -/*! Raises a client window above all others in its stacking layer +#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 window above all others in its stacking layer raiseWindow has a couple of constraints that lowerWindow does not.
- 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.
2) raiseWindow guarantees that XRestackWindows() will always 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 diff --git a/openbox/window.c b/openbox/window.c new file mode 100644 index 00000000..90de822f --- /dev/null +++ b/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; +} diff --git a/openbox/window.h b/openbox/window.h new file mode 100644 index 00000000..409697c1 --- /dev/null +++ b/openbox/window.h @@ -0,0 +1,35 @@ +#ifndef __window_h +#define __window_h + +#include + +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 diff --git a/plugins/resistance.c b/plugins/resistance.c index 4c2dad63..cc628492 100644 --- a/plugins/resistance.c +++ b/plugins/resistance.c @@ -65,6 +65,8 @@ static void resist_move(Client *c, int *x, int *y) 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; -- 2.45.2