From: Dana Jansens Date: Sun, 11 May 2003 23:31:43 +0000 (+0000) Subject: add internal popups n shit to the stacking list. X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=7c7868f47d42796a236c9a1813bed5fe9f0d4f41;p=chaz%2Fopenbox add internal popups n shit to the stacking list. some cleanups for the stacking order hint. add non-opaque move/resize. cant toggle it yet. --- diff --git a/openbox/event.c b/openbox/event.c index eecda14e..5a0d6a02 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -638,13 +638,13 @@ static void event_handle_client(Client *client, XEvent *e) switch (e->xconfigurerequest.detail) { case Below: case BottomIf: - stacking_lower(client); + stacking_lower(CLIENT_AS_WINDOW(client)); break; case Above: case TopIf: default: - stacking_raise(client); + stacking_raise(CLIENT_AS_WINDOW(client)); break; } } @@ -689,7 +689,7 @@ static void event_handle_client(Client *client, XEvent *e) if (client->shaded) client_shade(client, FALSE); client_focus(client); - stacking_raise(client); + stacking_raise(CLIENT_AS_WINDOW(client)); break; case ClientMessage: /* validate cuz we query stuff off the client here */ diff --git a/openbox/menu.c b/openbox/menu.c index d2d303cc..bfac0452 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -201,6 +201,7 @@ Menu *menu_new_full(char *label, char *name, Menu *parent, g_hash_table_insert(menu_hash, g_strdup(name), self); stacking_add(self); + stacking_raise(MENU_AS_WINDOW(self)); return self; } diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 7878b9f2..ddaa2762 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -1,10 +1,13 @@ #include "grab.h" #include "framerender.h" +#include "screen.h" #include "prop.h" #include "client.h" #include "dispatch.h" #include "openbox.h" #include "popup.h" +#include "render/render.h" +#include "render/theme.h" #include #include @@ -24,12 +27,21 @@ static guint button_return, button_escape, button_left, button_right, button_up, button_down; static Popup *popup = NULL; +static InternalWindow opaque_window = { { Window_Internal }, None }; +static GC opaque_gc = None; +static gboolean first_draw = FALSE; #define POPUP_X (10) #define POPUP_Y (10) +gboolean config_opaque_move = FALSE; +gboolean config_opaque_resize = FALSE; + void moveresize_startup() { + XSetWindowAttributes attrib; + XGCValues gcv; + button_return = XKeysymToKeycode(ob_display, XStringToKeysym("Return")); button_escape = XKeysymToKeycode(ob_display, XStringToKeysym("Escape")); button_left = XKeysymToKeycode(ob_display, XStringToKeysym("Left")); @@ -40,12 +52,30 @@ void moveresize_startup() popup = popup_new(FALSE); popup_size_to_string(popup, "W: 0000 W: 0000"); popup_position(popup, NorthWestGravity, POPUP_X, POPUP_Y); + + attrib.save_under = True; + opaque_window.win = XCreateWindow(ob_display, ob_root, 0, 0, 1, 1, 0, + render_depth, InputOutput, render_visual, + CWSaveUnder, &attrib); + stacking_add(&opaque_window); + stacking_raise(INTERNAL_AS_WINDOW(&opaque_window)); + + /* a GC to invert stuff */ + gcv.function = GXxor; + gcv.line_width = theme_bwidth; + gcv.foreground = (WhitePixel(ob_display, ob_screen) ^ + BlackPixel(ob_display, ob_screen)); + opaque_gc = XCreateGC(ob_display, opaque_window.win, + GCFunction | GCForeground | GCLineWidth, &gcv); } void moveresize_shutdown() { popup_free(popup); popup = NULL; + stacking_remove(&opaque_window); + XFreeGC(ob_display, opaque_gc); + XDestroyWindow(ob_display, opaque_window.win); } static void popup_coords(char *format, int a, int b) @@ -117,10 +147,25 @@ void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr) grab_pointer(TRUE, cur); grab_keyboard(TRUE); + + XResizeWindow(ob_display, opaque_window.win, screen_physical_size.width, + screen_physical_size.height); + stacking_raise(INTERNAL_AS_WINDOW(&opaque_window)); + if (corner == prop_atoms.net_wm_moveresize_move || + corner == prop_atoms.net_wm_moveresize_move_keyboard) { + if (!config_opaque_move) + XMapWindow(ob_display, opaque_window.win); + } else { + if (!config_opaque_resize) + XMapWindow(ob_display, opaque_window.win); + } + first_draw = TRUE; } void moveresize_end(gboolean cancel) { + XUnmapWindow(ob_display, opaque_window.win); + grab_keyboard(FALSE); grab_pointer(FALSE, None); @@ -145,12 +190,30 @@ void moveresize_end(gboolean cancel) static void do_move() { + int oldx, oldy, oldw, oldh; + dispatch_move(moveresize_client, &cur_x, &cur_y); + oldx = moveresize_client->frame->area.x; + oldy = moveresize_client->frame->area.y; + oldw = moveresize_client->frame->area.width; + oldh = moveresize_client->frame->area.height; /* get where the client should be */ frame_frame_gravity(moveresize_client->frame, &cur_x, &cur_y); client_configure(moveresize_client, Corner_TopLeft, cur_x, cur_y, start_cw, start_ch, TRUE, FALSE); + /* draw the new one */ + if (!config_opaque_move) + XDrawRectangle(ob_display, opaque_window.win, opaque_gc, + moveresize_client->frame->area.x, + moveresize_client->frame->area.y, + moveresize_client->frame->area.width - 1, + moveresize_client->frame->area.height - 1); + /* erase the old one */ + if (!config_opaque_move && !first_draw) + XDrawRectangle(ob_display, opaque_window.win, opaque_gc, + oldx, oldy, oldw - 1, oldh - 1); + first_draw = FALSE; /* this would be better with a fixed width font ... XXX can do it better if there are 2 text boxes */ @@ -160,6 +223,8 @@ static void do_move() static void do_resize() { + int oldx, oldy, oldw, oldh; + /* dispatch_resize needs the frame size */ cur_x += moveresize_client->frame->size.left + moveresize_client->frame->size.right; @@ -173,8 +238,25 @@ static void do_resize() cur_y -= moveresize_client->frame->size.top + moveresize_client->frame->size.bottom; - client_configure(moveresize_client, lockcorner, moveresize_client->area.x, - moveresize_client->area.y, cur_x, cur_y, TRUE, FALSE); + oldx = moveresize_client->frame->area.x; + oldy = moveresize_client->frame->area.y; + oldw = moveresize_client->frame->area.width; + oldh = moveresize_client->frame->area.height; + client_configure(moveresize_client, lockcorner, + moveresize_client->area.x, moveresize_client->area.y, + cur_x, cur_y, TRUE, FALSE); + /* draw the new one */ + if (!config_opaque_resize) + XDrawRectangle(ob_display, opaque_window.win, opaque_gc, + moveresize_client->frame->area.x, + moveresize_client->frame->area.y, + moveresize_client->frame->area.width - 1, + moveresize_client->frame->area.height - 1); + /* erase the old one */ + if (!config_opaque_resize && !first_draw) + XDrawRectangle(ob_display, opaque_window.win, opaque_gc, + oldx, oldy, oldw - 1, oldh - 1); + first_draw = FALSE; /* this would be better with a fixed width font ... XXX can do it better if there are 2 text boxes */ diff --git a/openbox/popup.c b/openbox/popup.c index f20aa006..17462d39 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -1,13 +1,18 @@ #include "openbox.h" #include "frame.h" +#include "window.h" +#include "stacking.h" #include "render/render.h" #include "render/theme.h" typedef struct Popup { - gboolean hasicon; + ObWindow obwin; Window bg; + Window icon; Window text; + + gboolean hasicon; Appearance *a_bg; Appearance *a_icon; Appearance *a_text; @@ -16,16 +21,21 @@ typedef struct Popup { int y; int w; int h; + gboolean mapped; } Popup; Popup *popup_new(gboolean hasicon) { Popup *self = g_new(Popup, 1); + self->obwin.type = Window_Internal; self->hasicon = hasicon; self->bg = None; self->a_text = NULL; self->gravity = NorthWestGravity; self->x = self->y = self->w = self->h = 0; + self->mapped = FALSE; + stacking_add(self); + stacking_raise(INTERNAL_AS_WINDOW(self)); return self; } @@ -41,6 +51,7 @@ void popup_free(Popup *self) } if (self->a_text) appearance_free(self->a_text); + stacking_remove(self); g_free(self); } @@ -206,10 +217,17 @@ void popup_show(Popup *self, char *text, Icon *icon) if (self->hasicon) paint(self->icon, self->a_icon); - XMapWindow(ob_display, self->bg); + if (!self->mapped) { + XMapWindow(ob_display, self->bg); + stacking_raise(INTERNAL_AS_WINDOW(self)); + self->mapped = TRUE; + } } void popup_hide(Popup *self) { - XUnmapWindow(ob_display, self->bg); + if (self->mapped) { + XUnmapWindow(ob_display, self->bg); + self->mapped = FALSE; + } } diff --git a/openbox/stacking.c b/openbox/stacking.c index 782a57dd..497450fe 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -26,14 +26,26 @@ void stacking_set_list() windows = g_new(Window, size); win_it = windows; for (it = g_list_last(stacking_list); it != NULL; - it = it->prev, ++win_it) - if (WINDOW_IS_CLIENT(it->data)) + it = it->prev) + if (WINDOW_IS_CLIENT(it->data)) { *win_it = window_top(it->data); + ++win_it; + } } else - windows = NULL; + windows = win_it = NULL; PROP_SETA32(ob_root, net_client_list_stacking, window, - (guint32*)windows, size); + (guint32*)windows, win_it - windows); + + g_print("Client list:"); + for (it = client_list; it; it = it->next) + g_print("0x%lx ", ((Client*)it->data)->window); + g_print("\n"); + g_print("Stacking order: "); + for (it = stacking_list; it; it = it->next) + if (WINDOW_IS_CLIENT(it->data)) + g_print("0x%lx ", ((Client*)it->data)->window); + g_print("\n"); if (windows) g_free(windows); diff --git a/openbox/window.c b/openbox/window.c index 90de822f..11f5e46b 100644 --- a/openbox/window.c +++ b/openbox/window.c @@ -13,6 +13,8 @@ Window window_top(ObWindow *self) return ((Slit*)self)->frame; case Window_Client: return ((Client*)self)->frame->window; + case Window_Internal: + return ((InternalWindow*)self)->win; } g_assert_not_reached(); return None; @@ -27,6 +29,8 @@ Window window_layer(ObWindow *self) return ((Slit*)self)->layer; case Window_Client: return ((Client*)self)->layer; + case Window_Internal: + return Layer_Internal; } g_assert_not_reached(); return None; diff --git a/openbox/window.h b/openbox/window.h index 409697c1..150323c7 100644 --- a/openbox/window.h +++ b/openbox/window.h @@ -6,16 +6,25 @@ typedef enum { Window_Menu, Window_Slit, - Window_Client + Window_Client, + Window_Internal } Window_InternalType; typedef struct ObWindow { Window_InternalType type; } ObWindow; +/* Wrapper for internal stuff. If its struct matches this then it can be used + as an ObWindow */ +typedef struct InternalWindow { + ObWindow obwin; + Window win; +} InternalWindow; + #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) +#define WINDOW_IS_INTERNAL(win) (((ObWindow*)win)->type == Window_Internal) struct Menu; struct Slit; @@ -24,10 +33,12 @@ 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 WINDOW_AS_INTERNAL(win) ((struct InternalWindow*)win) #define MENU_AS_WINDOW(menu) ((ObWindow*)menu) #define SLIT_AS_WINDOW(slit) ((ObWindow*)slit) #define CLIENT_AS_WINDOW(client) ((ObWindow*)client) +#define INTERNAL_AS_WINDOW(intern) ((ObWindow*)intern) Window window_top(ObWindow *self); Window window_layer(ObWindow *self);