From 9a99c1925b989a71e92b17dbb6658820050d771d Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 13 May 2007 17:54:46 +0000 Subject: [PATCH] merge r6434-6447 from trunk --- AUTHORS | 2 + COMPLIANCE | 13 +++ openbox/client.c | 154 ++++++++++++++++++---------- openbox/client.h | 12 ++- openbox/client_list_combined_menu.c | 4 +- openbox/client_list_menu.c | 4 +- openbox/client_menu.c | 4 +- openbox/event.c | 25 ++++- openbox/focus.c | 27 +++-- openbox/keyboard.c | 18 +++- openbox/keyboard.h | 2 + openbox/mainloop.c | 4 +- openbox/menu.c | 4 +- openbox/moveresize.c | 4 +- openbox/prop.c | 3 + openbox/prop.h | 3 + openbox/screen.c | 9 +- 17 files changed, 200 insertions(+), 92 deletions(-) diff --git a/AUTHORS b/AUTHORS index e4df36e0..4bc674db 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,3 +16,5 @@ Mike Bacso (smakwel@yahoo.com) - Themes John McKnight (jmcknight@gmail.com) - Clearlooks Themes +David Barr (david@chalkskeletons.com) + - Bear2 Theme diff --git a/COMPLIANCE b/COMPLIANCE index fdc40d1d..3873a8fd 100644 --- a/COMPLIANCE +++ b/COMPLIANCE @@ -63,3 +63,16 @@ the version of the spec which Openbox is compliant up to for the hint. + _NET_WM_FULL_PLACEMENT (1.4) + _NET_WM_MOVERESIZE_CANCEL (1.4) + _NET_REQUEST_FRAME_EXTENTS (1.3) ++ _NET_WM_ACTION_MOVE (1.3) ++ _NET_WM_ACTION_RESIZE (1.3) ++ _NET_WM_ACTION_MINIMIZE (1.3) ++ _NET_WM_ACTION_SHADE (1.3) +- _NET_WM_ACTION_STICK (1.3) + Openbox does not do large desktops, so no sticky state is needed. ++ _NET_WM_ACTION_MAXIMIZE_HORZ (1.3) ++ _NET_WM_ACTION_MAXIMIZE_VERT (1.3) ++ _NET_WM_ACTION_FULLSCREEN (1.3) ++ _NET_WM_ACTION_CHANGE_DESKTOP (1.3) ++ _NET_WM_ACTION_CLOSE (1.3) ++ _NET_WM_ACTION_ABOVE (1.4?) ++ _NET_WM_ACTION_BELOW (1.4?) diff --git a/openbox/client.c b/openbox/client.c index 208024cf..39bd94d5 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -64,7 +64,8 @@ typedef struct GList *client_list = NULL; -static GSList *client_destructors = NULL; +static GSList *client_destroy_notifies = NULL; +static GSList *client_hide_notifies = NULL; static void client_get_all(ObClient *self, gboolean real); static void client_toggle_border(ObClient *self, gboolean show); @@ -79,7 +80,7 @@ static void client_get_colormap(ObClient *self); static void client_change_allowed_actions(ObClient *self); static void client_change_state(ObClient *self); static void client_change_wm_state(ObClient *self); -static void client_apply_startup_state(ObClient *self, gint x, gint y); +static void client_apply_startup_state(ObClient *self); static void client_restore_session_state(ObClient *self); static gboolean client_restore_session_stacking(ObClient *self); static ObAppSettings *client_get_settings_state(ObClient *self); @@ -91,6 +92,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise); static GSList *client_search_all_top_parents_internal(ObClient *self, gboolean bylayer, ObStackingLayer layer); +static void client_call_notifies(ObClient *self, GSList *list); void client_startup(gboolean reconfig) { @@ -104,23 +106,57 @@ void client_shutdown(gboolean reconfig) if (reconfig) return; } -void client_add_destructor(ObClientCallback func, gpointer data) +static void client_call_notifies(ObClient *self, GSList *list) +{ + GSList *it; + + for (it = list; it; it = g_slist_next(it)) { + ClientCallback *d = it->data; + d->func(self, d->data); + } +} + +void client_add_destroy_notify(ObClientCallback func, gpointer data) +{ + ClientCallback *d = g_new(ClientCallback, 1); + d->func = func; + d->data = data; + client_destroy_notifies = g_slist_prepend(client_destroy_notifies, d); +} + +void client_remove_destroy_notify(ObClientCallback func) +{ + GSList *it; + + for (it = client_destroy_notifies; it; it = g_slist_next(it)) { + ClientCallback *d = it->data; + if (d->func == func) { + g_free(d); + client_destroy_notifies = + g_slist_delete_link(client_destroy_notifies, it); + break; + } + } +} + +void client_add_hide_notify(ObClientCallback func, gpointer data) { ClientCallback *d = g_new(ClientCallback, 1); d->func = func; d->data = data; - client_destructors = g_slist_prepend(client_destructors, d); + client_hide_notifies = g_slist_prepend(client_hide_notifies, d); } -void client_remove_destructor(ObClientCallback func) +void client_remove_hide_notify(ObClientCallback func) { GSList *it; - for (it = client_destructors; it; it = g_slist_next(it)) { + for (it = client_hide_notifies; it; it = g_slist_next(it)) { ClientCallback *d = it->data; if (d->func == func) { g_free(d); - client_destructors = g_slist_delete_link(client_destructors, it); + client_hide_notifies = + g_slist_delete_link(client_hide_notifies, it); break; } } @@ -229,7 +265,6 @@ void client_manage(Window window) XWMHints *wmhint; gboolean activate = FALSE; ObAppSettings *settings; - gint newx, newy; grab_server(TRUE); @@ -347,20 +382,21 @@ void client_manage(Window window) activate = TRUE; } - /* get the current position */ - newx = self->area.x; - newy = self->area.y; - /* figure out placement for the window */ if (ob_state() == OB_STATE_RUNNING) { gboolean transient; - transient = place_client(self, &newx, &newy, settings); + ob_debug("Positioned: %s @ %d %d\n", + (!self->positioned ? "no" : + (self->positioned == PPosition ? "program specified" : + (self->positioned == USPosition ? "user specified" : + "BADNESS !?"))), self->area.x, self->area.y); + + transient = place_client(self, &self->area.x, &self->area.y, settings); /* make sure the window is visible. */ - client_find_onscreen(self, &newx, &newy, - self->area.width, - self->area.height, + client_find_onscreen(self, &self->area.x, &self->area.y, + self->area.width, self->area.height, /* non-normal clients has less rules, and windows that are being restored from a session do also. we can assume you want @@ -383,12 +419,18 @@ void client_manage(Window window) also, this moves the window to the position where it has been placed */ ob_debug("placing window 0x%x at %d, %d with size %d x %d\n", - self->window, newx, newy, self->area.width, self->area.height); + self->window, self->area.x, self->area.y, + self->area.width, self->area.height); if (self->session) - ob_debug("session requested %d %d\n", + ob_debug(" but session requested %d %d instead, overriding\n", self->session->x, self->session->y); - client_apply_startup_state(self, newx, newy); + /* generate a ConfigureNotify telling the client where it is */ + client_configure_full(self, self->area.x, self->area.y, + self->area.width, self->area.height, + FALSE, TRUE); + + client_apply_startup_state(self); mouse_grab_for_client(self, TRUE); @@ -460,6 +502,7 @@ void client_manage(Window window) /* adjust the frame to the client's size before showing the window */ frame_adjust_area(self->frame, FALSE, TRUE, FALSE); + frame_adjust_client_area(self->frame); /* this has to happen before we try focus the window, but we want it to happen after the client's stacking has been determined or it looks bad @@ -565,10 +608,7 @@ void client_unmanage(ObClient *self) if (STRUT_EXISTS(self->strut)) screen_update_areas(); - for (it = client_destructors; it; it = g_slist_next(it)) { - ClientCallback *d = it->data; - d->func(self, d->data); - } + client_call_notifies(self, client_destroy_notifies); /* tell our parent(s) that we're gone */ if (self->transient_for == OB_TRAN_GROUP) { /* transient of group */ @@ -1560,7 +1600,9 @@ void client_setup_decor_and_functions(ObClient *self) OB_CLIENT_FUNC_ICONIFY | OB_CLIENT_FUNC_MAXIMIZE | OB_CLIENT_FUNC_SHADE | - OB_CLIENT_FUNC_CLOSE); + OB_CLIENT_FUNC_CLOSE | + OB_CLIENT_FUNC_BELOW | + OB_CLIENT_FUNC_ABOVE); if (!(self->min_size.width < self->max_size.width || self->min_size.height < self->max_size.height)) @@ -1592,10 +1634,15 @@ void client_setup_decor_and_functions(ObClient *self) self->functions = OB_CLIENT_FUNC_MOVE; case OB_CLIENT_TYPE_DESKTOP: - case OB_CLIENT_TYPE_DOCK: /* these windows are not manipulated by the window manager */ self->decorations = 0; self->functions = 0; + + case OB_CLIENT_TYPE_DOCK: + /* these windows are not manipulated by the window manager, but they + can set below layer which has a special meaning */ + self->decorations = 0; + self->functions = OB_CLIENT_FUNC_BELOW; break; } @@ -1685,7 +1732,7 @@ void client_setup_decor_and_functions(ObClient *self) static void client_change_allowed_actions(ObClient *self) { - gulong actions[9]; + gulong actions[11]; gint num = 0; /* desktop windows are kept on all desktops */ @@ -1708,6 +1755,10 @@ static void client_change_allowed_actions(ObClient *self) actions[num++] = prop_atoms.net_wm_action_maximize_horz; actions[num++] = prop_atoms.net_wm_action_maximize_vert; } + if (self->functions & OB_CLIENT_FUNC_ABOVE) + actions[num++] = prop_atoms.net_wm_action_above; + if (self->functions & OB_CLIENT_FUNC_BELOW) + actions[num++] = prop_atoms.net_wm_action_below; PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num); @@ -2383,6 +2434,8 @@ void client_hide(ObClient *self) { if (!client_should_show(self)) { frame_hide(self->frame); + + client_call_notifies(self, client_hide_notifies); } /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it @@ -2400,6 +2453,8 @@ void client_showhide(ObClient *self) } else { frame_hide(self->frame); + + client_call_notifies(self, client_hide_notifies); } /* According to the ICCCM (sec 4.1.3.1) when a window is not visible, it @@ -2438,17 +2493,8 @@ gboolean client_enter_focusable(ObClient *self) } -static void client_apply_startup_state(ObClient *self, gint x, gint y) +static void client_apply_startup_state(ObClient *self) { - gboolean pos = FALSE; /* has the window's position been configured? */ - gint ox, oy; - - /* save the position, and set self->area for these to use */ - ox = self->area.x; - oy = self->area.y; - self->area.x = x; - self->area.y = y; - /* set the desktop hint, to make sure that it always exists */ PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop); @@ -2461,7 +2507,6 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y) if (self->fullscreen) { self->fullscreen = FALSE; client_fullscreen(self, TRUE); - pos = TRUE; } if (self->undecorated) { self->undecorated = FALSE; @@ -2479,27 +2524,12 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y) if (self->max_vert && self->max_horz) { self->max_vert = self->max_horz = FALSE; client_maximize(self, TRUE, 0); - pos = TRUE; } else if (self->max_vert) { self->max_vert = FALSE; client_maximize(self, TRUE, 2); - pos = TRUE; } else if (self->max_horz) { self->max_horz = FALSE; client_maximize(self, TRUE, 1); - pos = TRUE; - } - - /* if the client didn't get positioned yet, then do so now. - call client_move even if the window is not being moved anywhere, because - when we reparent it and decorate it, it is getting moved and we need to - be telling it so with a ConfigureNotify event. - */ - if (!pos) { - /* use the saved position */ - self->area.x = ox; - self->area.y = oy; - client_move(self, x, y); } /* nothing to do for the other states: @@ -2713,8 +2743,9 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, (resized && config_resize_redraw)))); /* if the client is enlarging, then resize the client before the frame */ - if (send_resize_client && user && (w > oldw || h > oldh)) { - XResizeWindow(ob_display, self->window, MAX(w, oldw), MAX(h, oldh)); + if (send_resize_client && (w > oldw || h > oldh)) { + XResizeWindow(ob_display, self->window, + MAX(w, oldw), MAX(h, oldh)); /* resize the plate to show the client padding color underneath */ frame_adjust_client_area(self->frame); } @@ -2756,11 +2787,12 @@ void client_configure_full(ObClient *self, gint x, gint y, gint w, gint h, } /* if the client is shrinking, then resize the frame before the client */ - if (send_resize_client && (!user || (w <= oldw || h <= oldh))) { + if (send_resize_client && (w <= oldw || h <= oldh)) { /* resize the plate to show the client padding color underneath */ frame_adjust_client_area(self->frame); - XResizeWindow(ob_display, self->window, w, h); + if (send_resize_client) + XResizeWindow(ob_display, self->window, w, h); } XFlush(ob_display); @@ -3360,6 +3392,16 @@ gboolean client_focus(ObClient *self) "Focusing client \"%s\" at time %u\n", self->title, event_curtime); + /* if there is a grab going on, then we need to cancel it. if we move + focus during the grab, applications will get NotifyWhileGrabbed events + and ignore them ! + + actions should not rely on being able to move focus during an + interactive grab. + */ + if (keyboard_interactively_grabbed()) + keyboard_interactive_cancel(); + if (self->can_focus) { /* This can cause a BadMatch error with CurrentTime, or if an app passed in a bad time for _NET_WM_ACTIVE_WINDOW. */ diff --git a/openbox/client.h b/openbox/client.h index bc7c32e8..c4815d4c 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -71,7 +71,9 @@ typedef enum OB_CLIENT_FUNC_MAXIMIZE = 1 << 3, /*!< Allow to be maximized */ OB_CLIENT_FUNC_SHADE = 1 << 4, /*!< Allow to be shaded */ OB_CLIENT_FUNC_FULLSCREEN = 1 << 5, /*!< Allow to be made fullscreen */ - OB_CLIENT_FUNC_CLOSE = 1 << 6 /*!< Allow to be closed */ + OB_CLIENT_FUNC_CLOSE = 1 << 6, /*!< Allow to be closed */ + OB_CLIENT_FUNC_ABOVE = 1 << 7, /*!< Allow to be put in lower layer */ + OB_CLIENT_FUNC_BELOW = 1 << 8 /*!< Allow to be put in higher layer */ } ObFunctions; struct _ObClient @@ -309,8 +311,12 @@ typedef void (*ObClientCallback)(ObClient *client, gpointer data); /* Callback functions */ /*! Get notified when the client is unmanaged */ -void client_add_destructor(ObClientCallback func, gpointer data); -void client_remove_destructor(ObClientCallback func); +void client_add_destroy_notify(ObClientCallback func, gpointer data); +void client_remove_destroy_notify(ObClientCallback func); + +/*! Get notified when the client is hidden */ +void client_add_hide_notify(ObClientCallback func, gpointer data); +void client_remove_hide_notify(ObClientCallback func); /*! Manages all existing windows */ void client_manage_all(); diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c index 26430f35..52ebce43 100644 --- a/openbox/client_list_combined_menu.c +++ b/openbox/client_list_combined_menu.c @@ -143,7 +143,7 @@ static void client_dest(ObClient *client, gpointer data) void client_list_combined_menu_startup(gboolean reconfig) { if (!reconfig) - client_add_destructor(client_dest, NULL); + client_add_destroy_notify(client_dest, NULL); combined_menu = menu_new(MENU_NAME, _("Windows"), TRUE, NULL); menu_set_update_func(combined_menu, self_update); @@ -153,5 +153,5 @@ void client_list_combined_menu_startup(gboolean reconfig) void client_list_combined_menu_shutdown(gboolean reconfig) { if (!reconfig) - client_remove_destructor(client_dest); + client_remove_destroy_notify(client_dest); } diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c index 351790be..77cfc193 100644 --- a/openbox/client_list_menu.c +++ b/openbox/client_list_menu.c @@ -194,7 +194,7 @@ void client_list_menu_startup(gboolean reconfig) ObMenu *menu; if (!reconfig) - client_add_destructor(client_dest, NULL); + client_add_destroy_notify(client_dest, NULL); menu = menu_new(MENU_NAME, _("Desktops"), TRUE, NULL); menu_set_update_func(menu, self_update); @@ -203,5 +203,5 @@ void client_list_menu_startup(gboolean reconfig) void client_list_menu_shutdown(gboolean reconfig) { if (!reconfig) - client_remove_destructor(client_dest); + client_remove_destroy_notify(client_dest); } diff --git a/openbox/client_menu.c b/openbox/client_menu.c index 3699e212..758b6a7b 100644 --- a/openbox/client_menu.c +++ b/openbox/client_menu.c @@ -176,13 +176,13 @@ static gboolean layer_menu_update(ObMenuFrame *frame, gpointer data) if (e->type == OB_MENU_ENTRY_TYPE_NORMAL) { switch (e->id) { case LAYER_TOP: - *en = !c->above; + *en = !c->above && (c->functions & OB_CLIENT_FUNC_ABOVE); break; case LAYER_NORMAL: *en = c->above || c->below; break; case LAYER_BOTTOM: - *en = !c->below; + *en = !c->below && (c->functions & OB_CLIENT_FUNC_BELOW); break; default: *en = TRUE; diff --git a/openbox/event.c b/openbox/event.c index 15a8e128..9e72408d 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -131,7 +131,7 @@ void event_startup(gboolean reconfig) IceAddConnectionWatch(ice_watch, NULL); #endif - client_add_destructor(focus_delay_client_dest, NULL); + client_add_destroy_notify(focus_delay_client_dest, NULL); } void event_shutdown(gboolean reconfig) @@ -142,7 +142,7 @@ void event_shutdown(gboolean reconfig) IceRemoveConnectionWatch(ice_watch, NULL); #endif - client_remove_destructor(focus_delay_client_dest); + client_remove_destroy_notify(focus_delay_client_dest); } static Window event_get_window(XEvent *e) @@ -356,8 +356,13 @@ static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg) Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg) { + ObWindow *w; + + /* It is possible to get FocusIn events or unmanaged windows, meaning + they won't be for any known client */ return e->type == FocusIn && wanted_focusevent(e, TRUE) && - e->xfocus.window != screen_support_win; + (w = g_hash_table_lookup(window_map, &e->xfocus.window)) && + WINDOW_IS_CLIENT(w); } static void print_focusevent(XEvent *e) @@ -508,7 +513,19 @@ static void event_process(const XEvent *ec, gpointer data) if (!focus_left_screen) focus_fallback(TRUE); } - } else if (client && client != focus_client) { + } + else if (!client) { + /* It is possible to get FocusIn events or unmanaged windows, + meaning they won't be for any known client + + If this happens, set the client to NULL so we know focus + has wandered off, and we'll get a focus out for it + shortly. + */ + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to an invalid target\n"); + focus_set_client(NULL); + } + else if (client != focus_client) { focus_left_screen = FALSE; frame_adjust_focus(client->frame, TRUE); focus_set_client(client); diff --git a/openbox/focus.c b/openbox/focus.c index 92cd7662..b084d357 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -67,8 +67,8 @@ static gboolean valid_focus_target(ObClient *ft, gboolean all_desktops, gboolean dock_windows, gboolean desktop_windows); -static void focus_cycle_destructor(ObClient *client, gpointer data); -static void focus_tried_destructor(ObClient *client, gpointer data); +static void focus_cycle_destroy_notify(ObClient *client, gpointer data); +static void focus_tried_hide_notify(ObClient *client, gpointer data); static Window createWindow(Window parent, gulong mask, XSetWindowAttributes *attrib) @@ -86,8 +86,9 @@ void focus_startup(gboolean reconfig) if (!reconfig) { XSetWindowAttributes attr; - client_add_destructor(focus_cycle_destructor, NULL); - client_add_destructor(focus_tried_destructor, NULL); + client_add_destroy_notify(focus_cycle_destroy_notify, NULL); + client_add_destroy_notify(focus_tried_hide_notify, NULL); + client_add_hide_notify(focus_tried_hide_notify, NULL); /* start with nothing focused */ focus_nothing(); @@ -140,8 +141,9 @@ void focus_shutdown(gboolean reconfig) icon_popup_free(focus_cycle_popup); if (!reconfig) { - client_remove_destructor(focus_cycle_destructor); - client_remove_destructor(focus_tried_destructor); + client_remove_destroy_notify(focus_cycle_destroy_notify); + client_remove_destroy_notify(focus_tried_hide_notify); + client_remove_hide_notify(focus_tried_hide_notify); /* reset focus to root */ XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime); @@ -415,7 +417,7 @@ static void popup_cycle(ObClient *c, gboolean show, g_free(showtext); } -static void focus_cycle_destructor(ObClient *client, gpointer data) +static void focus_cycle_destroy_notify(ObClient *client, gpointer data) { /* end cycling if the target disappears. CurrentTime is fine, time won't be used @@ -741,10 +743,13 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, /* the currently selected window isn't interesting */ if(cur == c) continue; - if (!dock_windows && !desktop_windows && !client_normal(cur)) + if (cur->type == OB_CLIENT_TYPE_DOCK && !dock_windows) continue; - if (!(dock_windows && cur->type == OB_CLIENT_TYPE_DOCK) || - (desktop_windows && cur->type == OB_CLIENT_TYPE_DESKTOP)) + if (cur->type == OB_CLIENT_TYPE_DESKTOP && !desktop_windows) + continue; + if (!client_normal(cur) && + cur->type != OB_CLIENT_TYPE_DOCK && + cur->type != OB_CLIENT_TYPE_DESKTOP) continue; /* using c->desktop instead of screen_desktop doesn't work if the * current window was omnipresent, hope this doesn't have any other @@ -942,7 +947,7 @@ ObClient *focus_order_find_first(guint desktop) return NULL; } -static void focus_tried_destructor(ObClient *client, gpointer data) +static void focus_tried_hide_notify(ObClient *client, gpointer data) { XEvent ce; diff --git a/openbox/keyboard.c b/openbox/keyboard.c index d758b386..5cfd4571 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -199,11 +199,13 @@ static void keyboard_interactive_end(guint state, gboolean cancel, Time time, if (ungrab) grab_keyboard(FALSE); + /* set this before running the actions so they know the keyboard is not + grabbed */ + istate.active = FALSE; + alist = g_slist_append(NULL, istate.action); action_run_interactive(alist, istate.client, state, time, cancel, TRUE); g_slist_free(alist); - - istate.active = FALSE; } static void keyboard_interactive_end_client(ObClient *client, gpointer data) @@ -212,6 +214,12 @@ static void keyboard_interactive_end_client(ObClient *client, gpointer data) istate.client = NULL; } + +void keyboard_interactive_cancel() +{ + keyboard_interactive_end(0, TRUE, event_curtime, TRUE); +} + gboolean keyboard_interactive_grab(guint state, ObClient *client, ObAction *action) { @@ -324,16 +332,16 @@ void keyboard_startup(gboolean reconfig) popup = popup_new(FALSE); if (!reconfig) - client_add_destructor(keyboard_interactive_end_client, NULL); + client_add_destroy_notify(keyboard_interactive_end_client, NULL); } void keyboard_shutdown(gboolean reconfig) { if (!reconfig) - client_remove_destructor(keyboard_interactive_end_client); + client_remove_destroy_notify(keyboard_interactive_end_client); if (istate.active) - keyboard_interactive_end(0, TRUE, 0, TRUE); + keyboard_interactive_cancel(); ob_main_loop_timeout_remove(ob_main_loop, chain_timeout); diff --git a/openbox/keyboard.h b/openbox/keyboard.h index 4c6f3bb5..3d70448f 100644 --- a/openbox/keyboard.h +++ b/openbox/keyboard.h @@ -49,4 +49,6 @@ gboolean keyboard_process_interactive_grab(const XEvent *e, struct _ObClient **client); gboolean keyboard_interactively_grabbed(); +void keyboard_interactive_cancel(); + #endif diff --git a/openbox/mainloop.c b/openbox/mainloop.c index 2af81629..0e7b0b3c 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -282,7 +282,7 @@ void ob_main_loop_run(ObMainLoop *loop) loop->run = TRUE; loop->running = TRUE; - client_add_destructor(ob_main_loop_client_destroy, loop); + client_add_destroy_notify(ob_main_loop_client_destroy, loop); while (loop->run) { if (loop->signal_fired) { @@ -365,7 +365,7 @@ void ob_main_loop_run(ObMainLoop *loop) } } - client_remove_destructor(ob_main_loop_client_destroy); + client_remove_destroy_notify(ob_main_loop_client_destroy); loop->running = FALSE; } diff --git a/openbox/menu.c b/openbox/menu.c index c6e986b9..dbb0c701 100644 --- a/openbox/menu.c +++ b/openbox/menu.c @@ -110,13 +110,13 @@ void menu_startup(gboolean reconfig) g_assert(menu_parse_state.parent == NULL); if (!reconfig) - client_add_destructor(client_dest, NULL); + client_add_destroy_notify(client_dest, NULL); } void menu_shutdown(gboolean reconfig) { if (!reconfig) - client_remove_destructor(client_dest); + client_remove_destroy_notify(client_dest); parse_shutdown(menu_parse_inst); menu_parse_inst = NULL; diff --git a/openbox/moveresize.c b/openbox/moveresize.c index 6a1e2354..ac51f8b6 100644 --- a/openbox/moveresize.c +++ b/openbox/moveresize.c @@ -70,7 +70,7 @@ void moveresize_startup(gboolean reconfig) popup = popup_new(FALSE); if (!reconfig) - client_add_destructor(client_dest, NULL); + client_add_destroy_notify(client_dest, NULL); } void moveresize_shutdown(gboolean reconfig) @@ -78,7 +78,7 @@ void moveresize_shutdown(gboolean reconfig) if (!reconfig) { if (moveresize_in_progress) moveresize_end(FALSE); - client_remove_destructor(client_dest); + client_remove_destroy_notify(client_dest); } popup_free(popup); diff --git a/openbox/prop.c b/openbox/prop.c index e0559068..5b611f2d 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -135,6 +135,9 @@ void prop_startup() CREATE(net_wm_action_fullscreen, "_NET_WM_ACTION_FULLSCREEN"); CREATE(net_wm_action_change_desktop, "_NET_WM_ACTION_CHANGE_DESKTOP"); CREATE(net_wm_action_close, "_NET_WM_ACTION_CLOSE"); + CREATE(net_wm_action_above, "_NET_WM_ACTION_ABOVE"); + CREATE(net_wm_action_below, "_NET_WM_ACTION_BELOW"); + CREATE(net_wm_state_modal, "_NET_WM_STATE_MODAL"); /* CREATE(net_wm_state_sticky, "_NET_WM_STATE_STICKY");*/ CREATE(net_wm_state_maximized_vert, "_NET_WM_STATE_MAXIMIZED_VERT"); diff --git a/openbox/prop.h b/openbox/prop.h index d1d6a516..8f81eff0 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -155,11 +155,14 @@ typedef struct Atoms { Atom net_wm_action_resize; Atom net_wm_action_minimize; Atom net_wm_action_shade; +/* Atom net_wm_action_stick;*/ Atom net_wm_action_maximize_horz; Atom net_wm_action_maximize_vert; Atom net_wm_action_fullscreen; Atom net_wm_action_change_desktop; Atom net_wm_action_close; + Atom net_wm_action_above; + Atom net_wm_action_below; Atom net_wm_state_modal; /* Atom net_wm_state_sticky;*/ diff --git a/openbox/screen.c b/openbox/screen.c index 73cc4f14..1cbb2a5e 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -258,6 +258,8 @@ gboolean screen_annex(const gchar *program_name) supported[i++] = prop_atoms.net_wm_action_fullscreen; supported[i++] = prop_atoms.net_wm_action_change_desktop; supported[i++] = prop_atoms.net_wm_action_close; + supported[i++] = prop_atoms.net_wm_action_above; + supported[i++] = prop_atoms.net_wm_action_below; supported[i++] = prop_atoms.net_wm_state; supported[i++] = prop_atoms.net_wm_state_modal; supported[i++] = prop_atoms.net_wm_state_maximized_vert; @@ -310,8 +312,13 @@ void screen_startup(gboolean reconfig) desktop_cycle_popup = pager_popup_new(FALSE); pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT); - if (reconfig) + if (reconfig) { + /* update the pager popup's width */ + pager_popup_text_width_to_strings(desktop_cycle_popup, + screen_desktop_names, + screen_num_desktops); return; + } /* get the initial size */ screen_resize(); -- 2.34.1