From 2d6efece61a752a69ebe0287ceff21c88739e60d Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 8 Dec 2009 14:21:26 -0500 Subject: [PATCH 01/30] Follow up for commit 7f36e21ea9d86df5e6fa62d2888891ed957c4639 The actions/session.c file was removed. --- po/POTFILES.in | 1 - 1 file changed, 1 deletion(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index bb6beff8..85938dee 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,7 +2,6 @@ openbox/actions.c openbox/actions/execute.c openbox/actions/exit.c -openbox/actions/session.c openbox/client.c openbox/client_list_combined_menu.c openbox/client_list_menu.c From 4e0a4fb53b859d818a4184564a441fce29c12be0 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 8 Dec 2009 15:18:57 -0500 Subject: [PATCH 02/30] Make openbox-gnome-session work with gnome-session > 2.22 --- data/xsession/openbox-gnome-session.in | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/data/xsession/openbox-gnome-session.in b/data/xsession/openbox-gnome-session.in index 278ac6a8..d93bab0c 100644 --- a/data/xsession/openbox-gnome-session.in +++ b/data/xsession/openbox-gnome-session.in @@ -7,6 +7,27 @@ if test -n "$1"; then exit fi +VER=$(gnome-session --version 2>/dev/null | \ + sed -e 's/[^0-9.]*\([0-9.]\+\)/\1/') + +MAJOR=$(echo $VER | cut -d . -f 1) +MINOR=$(echo $VER | cut -d . -f 2) + # Run GNOME with Openbox as its window manager export WINDOW_MANAGER="@bindir@/openbox" -exec gnome-session --choose-session=openbox-session "$@" + +if test $MAJOR -lt 2 || (test $MAJOR = 2 && test $MINOR -le 22); then + # old gnome-session allows multiple sessions to be saved + exec gnome-session --choose-session=openbox-session "$@" +else + # make sure the gnome-wm script is being used + gconftool-2 -t string \ + -s /desktop/gnome/session/required_components/windowmanager "gnome-wm" \ + 2> /dev/null + + # new gnome-session does not allow multiple sessions + exec gnome-session "$@" +fi + + + From 0c0ddc36289f39ee32347e775147e7300ce6cf89 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 10:09:43 -0500 Subject: [PATCH 03/30] Fix stacking for transients vs helper windows. Fixes bug #3851 This allows transient windows to be above helper windows. And generally keeps helper windows below transients, unless they are raised directly. --- openbox/stacking.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/openbox/stacking.c b/openbox/stacking.c index 4c24e3e8..1638908b 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -216,6 +216,7 @@ static void restack_windows(ObClient *selected, gboolean raise) GList *it, *last, *below, *above, *next; GList *wins = NULL; + GList *group_helpers = NULL; GList *group_modals = NULL; GList *group_trans = NULL; GList *modals = NULL; @@ -246,6 +247,8 @@ static void restack_windows(ObClient *selected, gboolean raise) /* only move windows in the same stacking layer */ if (ch->layer == selected->layer && + /* looking for windows that are transients, and so would + remain above the selected window */ client_search_transient(selected, ch)) { if (client_is_direct_child(selected, ch)) { @@ -254,6 +257,13 @@ static void restack_windows(ObClient *selected, gboolean raise) else trans = g_list_prepend(trans, ch); } + else if (client_helper(ch)) { + if (selected->transient) { + /* helpers do not stay above transient windows */ + continue; + } + group_helpers = g_list_prepend(group_helpers, ch); + } else { if (ch->modal) group_modals = g_list_prepend(group_modals, ch); @@ -266,8 +276,13 @@ static void restack_windows(ObClient *selected, gboolean raise) } } - /* put transients of the selected window right above it */ + /* put modals above other direct transients */ wins = g_list_concat(modals, trans); + + /* put helpers below direct transients */ + wins = g_list_concat(wins, group_helpers); + + /* put the selected window right below these children */ wins = g_list_append(wins, selected); /* if selected window is transient for group then raise it above others */ From 5290af9f50c8492398e9f1c61be8f659106bc591 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 10:23:00 -0500 Subject: [PATCH 04/30] Use test -r instead of test -e for solaris. Fixes bug #4253. --- data/xsession/openbox-session.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/xsession/openbox-session.in b/data/xsession/openbox-session.in index 259dc580..7c3daa73 100644 --- a/data/xsession/openbox-session.in +++ b/data/xsession/openbox-session.in @@ -10,10 +10,10 @@ fi AUTOSTART="${XDG_CONFIG_HOME:-"$HOME/.config"}/openbox/autostart.sh" GLOBALAUTOSTART="@configdir@/openbox/autostart.sh" -if test -e $AUTOSTART; then +if test -r $AUTOSTART; then . $AUTOSTART else - if test -e $GLOBALAUTOSTART; then + if test -r $GLOBALAUTOSTART; then . $GLOBALAUTOSTART fi fi From 301122057283400dda30cd8ed04c7b7b69e4a912 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 10:32:36 -0500 Subject: [PATCH 05/30] Set a minimum value for the screenEdgeWarpTime for 25ms. When this is very small it just gives X/Openbox a heart attack and ends up going forever. Even 25 is quite too fast to be usuable so it should be a good minimum. --- openbox/config.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openbox/config.c b/openbox/config.c index 96fdd0f4..9b6c2028 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -444,8 +444,13 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, config_mouse_threshold = parse_int(doc, n); if ((n = parse_find_node("doubleClickTime", node))) config_mouse_dclicktime = parse_int(doc, n); - if ((n = parse_find_node("screenEdgeWarpTime", node))) + if ((n = parse_find_node("screenEdgeWarpTime", node))) { config_mouse_screenedgetime = parse_int(doc, n); + /* minimum value of 25 for this property, when it is 1 and you hit the + edge it basically never stops */ + if (config_mouse_screenedgetime && config_mouse_screenedgetime < 25) + config_mouse_screenedgetime = 25; + } n = parse_find_node("context", node); while (n) { From cf033623a0f5519a42d13119db5e023ffe08a1ac Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 10:56:43 -0500 Subject: [PATCH 06/30] Allow skip_taskbar windows to be focused on map when the user requests it in rc.xml. Fixes bug #4350 --- openbox/client.c | 3 ++- openbox/focus.c | 16 ++++++++++------ openbox/focus.h | 3 ++- openbox/focus_cycle.c | 10 ++++++---- openbox/focus_cycle_popup.c | 3 ++- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index a91b9503..c4576952 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -370,7 +370,8 @@ void client_manage(Window window, ObPrompt *prompt) (user_time != 0) && /* this checks for focus=false for the window */ (!settings || settings->focus != 0) && - focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE)) + focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE, + settings->focus == 1)) { activate = TRUE; } diff --git a/openbox/focus.c b/openbox/focus.c index 8c3bd70a..7eea6c39 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -130,7 +130,7 @@ static ObClient* focus_fallback_target(gboolean allow_refocus, 3. it is not shaded */ if ((allow_omnipresent || c->desktop == screen_desktop) && - focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, FALSE) && + focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) && !c->shaded && (allow_refocus || client_focus_target(c) != old) && client_focus(c)) @@ -150,7 +150,7 @@ static ObClient* focus_fallback_target(gboolean allow_refocus, a splashscreen or a desktop window (save the desktop as a backup fallback though) */ - if (focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, TRUE) && + if (focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) && (allow_refocus || client_focus_target(c) != old) && client_focus(c)) { @@ -281,7 +281,7 @@ static gboolean focus_target_has_siblings(ObClient *ft, /* check that it's not a helper window to avoid infinite recursion */ if (c != ft && c->type == OB_CLIENT_TYPE_NORMAL && focus_valid_target(c, TRUE, iconic_windows, all_desktops, - FALSE, FALSE)) + FALSE, FALSE, FALSE)) { return TRUE; } @@ -294,7 +294,8 @@ gboolean focus_valid_target(ObClient *ft, gboolean iconic_windows, gboolean all_desktops, gboolean dock_windows, - gboolean desktop_windows) + gboolean desktop_windows, + gboolean user_request) { gboolean ok = FALSE; @@ -333,9 +334,11 @@ gboolean focus_valid_target(ObClient *ft, !focus_target_has_siblings(ft, iconic_windows, all_desktops)))); /* it's not set to skip the taskbar (but this only applies to normal typed - windows, and is overridden if the window is modal) */ + windows, and is overridden if the window is modal or if the user asked + for this window to be focused) */ ok = ok && (ft->type != OB_CLIENT_TYPE_NORMAL || ft->modal || + user_request || !ft->skip_taskbar); /* it's not going to just send focus off somewhere else (modal window), @@ -348,7 +351,8 @@ gboolean focus_valid_target(ObClient *ft, iconic_windows, all_desktops, dock_windows, - desktop_windows)); + desktop_windows, + FALSE)); } return ok; diff --git a/openbox/focus.h b/openbox/focus.h index b8f89994..19ab406e 100644 --- a/openbox/focus.h +++ b/openbox/focus.h @@ -69,6 +69,7 @@ gboolean focus_valid_target(struct _ObClient *ft, gboolean iconic_windows, gboolean all_desktops, gboolean dock_windows, - gboolean desktop_windows); + gboolean desktop_windows, + gboolean user_request); #endif diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c index e30672dc..20a738f4 100644 --- a/openbox/focus_cycle.c +++ b/openbox/focus_cycle.c @@ -60,7 +60,8 @@ void focus_cycle_stop(ObClient *ifclient) focus_cycle_iconic_windows, focus_cycle_all_desktops, focus_cycle_dock_windows, - focus_cycle_desktop_windows)) + focus_cycle_desktop_windows, + FALSE)) { focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE); focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); @@ -122,7 +123,8 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, focus_cycle_iconic_windows, focus_cycle_all_desktops, focus_cycle_dock_windows, - focus_cycle_desktop_windows)) + focus_cycle_desktop_windows, + FALSE)) { if (interactive) { if (ft != focus_cycle_target) { /* prevents flicker */ @@ -189,7 +191,7 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, if (cur == c) continue; if (!focus_valid_target(it->data, TRUE, FALSE, FALSE, dock_windows, - desktop_windows)) + desktop_windows, FALSE)) continue; /* find the centre coords of this window, from the @@ -297,7 +299,7 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, focus_cycle_iconic_windows, focus_cycle_all_desktops, focus_cycle_dock_windows, - focus_cycle_desktop_windows)) + focus_cycle_desktop_windows, FALSE)) ft = it->data; } diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index df3558df..53a7eb09 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -185,7 +185,8 @@ static void popup_setup(ObFocusCyclePopup *p, gboolean create_targets, iconic_windows, all_desktops, dock_windows, - desktop_windows)) + desktop_windows, + FALSE)) { gchar *text = popup_get_name(ft); From d95355ce5830d8e3377729c0a264c5823ca9a06d Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 11:02:44 -0500 Subject: [PATCH 07/30] Add a WM_CLASS to the skiptaskbar test --- tests/skiptaskbar.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/skiptaskbar.c b/tests/skiptaskbar.c index 1b246160..bb585c6e 100644 --- a/tests/skiptaskbar.c +++ b/tests/skiptaskbar.c @@ -26,6 +26,7 @@ int main () { Window win; XEvent report; Atom state, skip; + XClassHint classhint; int x=10,y=10,h=400,w=400; display = XOpenDisplay(NULL); @@ -47,6 +48,10 @@ int main () { XChangeProperty(display, win, state, XA_ATOM, 32, PropModeReplace, (unsigned char*)&skip, 1); + classhint.res_name = "test"; + classhint.res_class = "Test"; + XSetClassHint(display, win, &classhint); + XMapWindow(display, win); XFlush(display); From 36af6f8d968eb53a836b9db1d64f007e3ffca271 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 11:24:16 -0500 Subject: [PATCH 08/30] Fully maximized windows still have a normal titlebar. Fixes bug #4373 Also, maximized windows were having their client padding reduced by the size of the outer border from this same bug, which is now fixed. --- openbox/frame.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openbox/frame.c b/openbox/frame.c index c1b31570..df53f3c2 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -370,8 +370,7 @@ void frame_adjust_area(ObFrame *self, gboolean moved, STRUT_SET(self->size, self->cbwidth_l + (!self->max_horz ? self->bwidth : 0), - self->cbwidth_t + - (!self->max_horz || !self->max_vert ? self->bwidth : 0), + self->cbwidth_t + self->bwidth, self->cbwidth_r + (!self->max_horz ? self->bwidth : 0), self->cbwidth_b + (!self->max_horz || !self->max_vert ? self->bwidth : 0)); From 5b20b3fc7fbfc76ce36f33e98c8a0467fa204ec5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 13:22:37 -0500 Subject: [PATCH 09/30] Add a focus debug message for the frame's visible focus state --- openbox/frame.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openbox/frame.c b/openbox/frame.c index df53f3c2..20697d32 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -23,6 +23,7 @@ #include "extensions.h" #include "prop.h" #include "grab.h" +#include "debug.h" #include "config.h" #include "framerender.h" #include "mainloop.h" @@ -948,6 +949,9 @@ void frame_adjust_state(ObFrame *self) void frame_adjust_focus(ObFrame *self, gboolean hilite) { + ob_debug_type(OB_DEBUG_FOCUS, + "Frame for 0x%x has focus: %d\n", + self->client->window, hilite); self->focused = hilite; self->need_render = TRUE; framerender_frame(self); From d7d54e9b892ce8ce23994720d34aa29fd47b8fd8 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 13:23:03 -0500 Subject: [PATCH 10/30] The colormap is being set twice when moving focus to the root window --- openbox/focus.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openbox/focus.c b/openbox/focus.c index 7eea6c39..a0e9c666 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -184,12 +184,6 @@ ObClient* focus_fallback(gboolean allow_refocus, gboolean allow_pointer, void focus_nothing(void) { - /* Install our own colormap */ - if (focus_client != NULL) { - screen_install_colormap(focus_client, FALSE); - screen_install_colormap(NULL, TRUE); - } - /* nothing is focused, update the colormap and _the root property_ */ focus_set_client(NULL); From 9f74f1e244d90a60aa33e5921a66bb22e3faf073 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 13:23:18 -0500 Subject: [PATCH 11/30] When moving focus across desktops, make sure Openbox doesn't think that a window which is no longer visible is still focused. --- openbox/screen.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openbox/screen.c b/openbox/screen.c index 3e27903f..b0fa17dd 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -727,6 +727,15 @@ void screen_set_desktop(guint num, gboolean dofocus) if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; client_hide(c); + if (c == focus_client) { + /* c was focused and we didn't do fallback clearly so make sure + openbox doesnt still consider the window focused. + this happens when using NextWindow with allDesktops, since + it doesnt want to move focus on desktop change, but the + focus is not going to stay with the current window, which + has now disappeared */ + focus_set_client(NULL); + } } } From 324ba15ebc79eb95cf6ec9c0f7d42250fc30f11b Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 13:25:19 -0500 Subject: [PATCH 12/30] Fix the Focus/Activate actions to focus windows on other desktops correctly --- openbox/actions/focus.c | 3 ++- openbox/client.c | 5 +++-- openbox/client.h | 7 +++++-- openbox/client_list_combined_menu.c | 2 +- openbox/client_list_menu.c | 2 +- openbox/event.c | 4 ++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/openbox/actions/focus.c b/openbox/actions/focus.c index 0ef9d268..8da8ed5e 100644 --- a/openbox/actions/focus.c +++ b/openbox/actions/focus.c @@ -2,6 +2,7 @@ #include "openbox/event.h" #include "openbox/client.h" #include "openbox/focus.h" +#include "openbox/screen.h" typedef struct { gboolean here; @@ -56,7 +57,7 @@ static gboolean run_func(ObActionsData *data, gpointer options) data->context != OB_FRAME_CONTEXT_FRAME)) { actions_client_move(data, TRUE); - client_activate(data->client, o->here, FALSE, FALSE, TRUE); + client_activate(data->client, TRUE, o->here, FALSE, FALSE, TRUE); actions_client_move(data, FALSE); } } else if (data->context == OB_FRAME_CONTEXT_DESKTOP) { diff --git a/openbox/client.c b/openbox/client.c index c4576952..b3f95364 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -3931,7 +3931,8 @@ static void client_present(ObClient *self, gboolean here, gboolean raise, } /* this function exists to map to the net_active_window message in the ewmh */ -void client_activate(ObClient *self, gboolean desktop, gboolean raise, +void client_activate(ObClient *self, gboolean desktop, + gboolean here, gboolean raise, gboolean unshade, gboolean user) { if ((user && (desktop || @@ -3939,7 +3940,7 @@ void client_activate(ObClient *self, gboolean desktop, gboolean raise, self->desktop == screen_desktop)) || client_can_steal_focus(self, event_curtime, CurrentTime)) { - client_present(self, FALSE, raise, unshade); + client_present(self, here, raise, unshade); } else client_hilite(self, TRUE); diff --git a/openbox/client.h b/openbox/client.h index 15ae2220..3b1e042c 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -577,13 +577,16 @@ gboolean client_focus(ObClient *self); when the user deliberately selects a window for use. @param desktop If true, and the window is on another desktop, it will still be activated. + @param here If true, and the window is on another desktop, it will be moved + to the current desktop, otherwise the desktop will switch to + where the window is. @param raise If true, the client is brought to the front. @param unshade If true, the client is unshaded (if it is shaded) @param user If true, then a user action is what requested the activation; otherwise, it means an application requested it on its own */ -void client_activate(ObClient *self, gboolean desktop, gboolean raise, - gboolean unshade, gboolean user); +void client_activate(ObClient *self, gboolean desktop, gboolean here, + gboolean raise, gboolean unshade, gboolean user); /*! Bring all of its helper windows to its desktop. These are the utility and stuff windows. */ diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c index ad23cd48..593010eb 100644 --- a/openbox/client_list_combined_menu.c +++ b/openbox/client_list_combined_menu.c @@ -114,7 +114,7 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f, else { ObClient *t = self->data.normal.data; if (t) { /* it's set to NULL if its destroyed */ - client_activate(t, TRUE, TRUE, TRUE, TRUE); + client_activate(t, TRUE, FALSE, TRUE, TRUE, TRUE); /* if the window is omnipresent then we need to go to its desktop */ if (t->desktop == DESKTOP_ALL) diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c index ca4534ba..2e87259b 100644 --- a/openbox/client_list_menu.c +++ b/openbox/client_list_menu.c @@ -101,7 +101,7 @@ static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f, { ObClient *t = self->data.normal.data; if (t) { /* it's set to NULL if its destroyed */ - client_activate(t, TRUE, TRUE, TRUE, TRUE); + client_activate(t, TRUE, FALSE, TRUE, TRUE, TRUE); /* if the window is omnipresent then we need to go to its desktop */ if (t->desktop == DESKTOP_ALL) diff --git a/openbox/event.c b/openbox/event.c index e07d6a31..b4bd8270 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1276,7 +1276,7 @@ static void event_handle_client(ObClient *client, XEvent *e) it can happen now when the window is on another desktop, but we still don't want it! */ - client_activate(client, FALSE, TRUE, TRUE, TRUE); + client_activate(client, FALSE, FALSE, TRUE, TRUE, TRUE); break; case ClientMessage: /* validate cuz we query stuff off the client here */ @@ -1332,7 +1332,7 @@ static void event_handle_client(ObClient *client, XEvent *e) ob_debug_type(OB_DEBUG_APP_BUGS, "_NET_ACTIVE_WINDOW message for window %s is " "missing source indication\n", client->title); - client_activate(client, FALSE, TRUE, TRUE, + client_activate(client, FALSE, FALSE, TRUE, TRUE, (e->xclient.data.l[0] == 0 || e->xclient.data.l[0] == 2)); } else if (msgtype == prop_atoms.net_wm_moveresize) { From 437739b6a3399765747b09b0777b1db9d0e6b483 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 13:47:38 -0500 Subject: [PATCH 13/30] Fix for rendering RGBA and Image textures. RGBA and Image textures could exceed their tarea if given an x or y offset inside the area that is > 0. --- render/render.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/render/render.c b/render/render.c index 7c00c146..20002e32 100644 --- a/render/render.c +++ b/render/render.c @@ -135,12 +135,14 @@ Pixmap RrPaintPixmap(RrAppearance *a, gint w, gint h) { RrRect narea = tarea; RrTextureImage *img = &a->texture[i].data.image; - if (img->twidth) - narea.width = MIN(tarea.width, img->twidth); - if (img->theight) - narea.height = MIN(tarea.height, img->theight); narea.x += img->tx; + narea.width -= img->tx; narea.y += img->ty; + narea.height -= img->ty; + if (img->twidth) + narea.width = MIN(narea.width, img->twidth); + if (img->theight) + narea.height = MIN(narea.height, img->theight); RrImageDrawImage(a->surface.pixel_data, &a->texture[i].data.image, a->w, a->h, @@ -153,12 +155,14 @@ Pixmap RrPaintPixmap(RrAppearance *a, gint w, gint h) { RrRect narea = tarea; RrTextureRGBA *rgb = &a->texture[i].data.rgba; - if (rgb->twidth) - narea.width = MIN(tarea.width, rgb->twidth); - if (rgb->theight) - narea.height = MIN(tarea.height, rgb->theight); narea.x += rgb->tx; + narea.width -= rgb->tx; narea.y += rgb->ty; + narea.height -= rgb->ty; + if (rgb->twidth) + narea.width = MIN(narea.width, rgb->twidth); + if (rgb->theight) + narea.height = MIN(narea.height, rgb->theight); RrImageDrawRGBA(a->surface.pixel_data, &a->texture[i].data.rgba, a->w, a->h, From 543828c23f36315e27516a88b7bd0bc8998e741c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 14:00:51 -0500 Subject: [PATCH 14/30] Properly react when a client's strut changes. Previously it would only react if the height of the strut changed, not if its start/end changed (that was a long-standing bug). --- openbox/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbox/client.c b/openbox/client.c index b3f95364..030e893a 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -2111,7 +2111,7 @@ void client_update_strut(ObClient *self) STRUT_PARTIAL_SET(strut, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - if (!STRUT_EQUAL(strut, self->strut)) { + if (!PARTIAL_STRUT_EQUAL(strut, self->strut)) { self->strut = strut; /* updating here is pointless while we're being mapped cuz we're not in From 7a926bb82fc724b3a1b50a385b4040ab7fee6878 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 14:59:18 -0500 Subject: [PATCH 15/30] Find a valid image to use in the image cache. Fixes bug #1149 The larger of the width and height has to match. If the smaller matches, then it would have to be resized down to fit inside the area, so that does not count. --- render/image.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/render/image.c b/render/image.c index 96486437..c8e839ce 100644 --- a/render/image.c +++ b/render/image.c @@ -221,7 +221,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src, return pic; } -/*! This drawns an RGBA picture into the target, within the rectangle specified +/*! This draws an RGBA picture into the target, within the rectangle specified by the area parameter. If the area's size differs from the source's then it will be centered within the rectangle */ void DrawRGBA(RrPixel32 *target, gint target_w, gint target_h, @@ -405,11 +405,13 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img, pic = NULL; free_pic = FALSE; - /* is there an original of this size? (only w or h has to be right cuz - we maintain aspect ratios) */ + /* is there an original of this size? (only the larger of + w or h has to be right cuz we maintain aspect ratios) */ for (i = 0; i < self->n_original; ++i) - if (self->original[i]->width == area->width || - self->original[i]->height == area->height) + if ((self->original[i]->width >= self->original[i]->height && + self->original[i]->width == area->width) || + (self->original[i]->width <= self->original[i]->height && + self->original[i]->height == area->height)) { pic = self->original[i]; break; @@ -417,8 +419,10 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img, /* is there a resize of this size? */ for (i = 0; i < self->n_resized; ++i) - if (self->resized[i]->width == area->width || - self->resized[i]->height == area->height) + if ((self->resized[i]->width >= self->resized[i]->height && + self->resized[i]->width == area->width) || + (self->resized[i]->width <= self->resized[i]->height && + self->resized[i]->height == area->height)) { gint j; RrImagePic *saved; From e0015160f0bc79ef0ad2de1ad7cc9bb389ccddc9 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 15:41:28 -0500 Subject: [PATCH 16/30] Make the default placement on the active monitor (Any is madness) --- data/rc.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/rc.xml b/data/rc.xml index ebe2f310..d5d3eafa 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -35,7 +35,7 @@
yes
- Any + Active From ade3b4dd69cf275bbaf5de663e1b723d6c073eb1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 16:00:32 -0500 Subject: [PATCH 17/30] Make the edge detection fully include monitor edges. This fixes the move-to-edge behaviour, when moving past the edge of a monitor, the window will stop with its tail edge against the inside of the monitor's edge. --- openbox/client.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index 030e893a..fcbe7cd9 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -4237,39 +4237,26 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, gint *dest, gboolean *near_edge) { GList *it; - Rect *a, *mon; + Rect *a; Rect dock_area; gint edge; + guint i; a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS, &self->frame->area); - mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR, - &self->frame->area); switch (dir) { case OB_DIRECTION_NORTH: - if (my_head >= RECT_TOP(*mon) + 1) - edge = RECT_TOP(*mon) - 1; - else - edge = RECT_TOP(*a) - 1; + edge = RECT_TOP(*a) - 1; break; case OB_DIRECTION_SOUTH: - if (my_head <= RECT_BOTTOM(*mon) - 1) - edge = RECT_BOTTOM(*mon) + 1; - else - edge = RECT_BOTTOM(*a) + 1; + edge = RECT_BOTTOM(*a) + 1; break; case OB_DIRECTION_EAST: - if (my_head <= RECT_RIGHT(*mon) - 1) - edge = RECT_RIGHT(*mon) + 1; - else - edge = RECT_RIGHT(*a) + 1; + edge = RECT_RIGHT(*a) + 1; break; case OB_DIRECTION_WEST: - if (my_head >= RECT_LEFT(*mon) + 1) - edge = RECT_LEFT(*mon) - 1; - else - edge = RECT_LEFT(*a) - 1; + edge = RECT_LEFT(*a) - 1; break; default: g_assert_not_reached(); @@ -4278,6 +4265,15 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, *dest = edge; *near_edge = TRUE; + /* search for edges of monitors */ + for (i = 0; i < screen_num_monitors; ++i) { + Rect *area = screen_area(self->desktop, i, NULL); + detect_edge(*area, dir, my_head, my_size, my_edge_start, + my_edge_size, dest, near_edge); + g_free(area); + } + + /* search for edges of clients */ for (it = client_list; it; it = g_list_next(it)) { ObClient *cur = it->data; @@ -4299,7 +4295,6 @@ void client_find_edge_directional(ObClient *self, ObDirection dir, detect_edge(dock_area, dir, my_head, my_size, my_edge_start, my_edge_size, dest, near_edge); g_free(a); - g_free(mon); } void client_find_move_directional(ObClient *self, ObDirection dir, From 10d99cc5e9efe40527c6ace3740b67890ea37729 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 16:26:15 -0500 Subject: [PATCH 18/30] Bug in choosing the active monitor when doing a move/resize --- openbox/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbox/screen.c b/openbox/screen.c index b0fa17dd..899b4bc3 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -1729,7 +1729,7 @@ Rect* screen_physical_area_active(void) gint x, y; if (moveresize_client) - a = screen_physical_area_monitor(client_monitor(focus_client)); + a = screen_physical_area_monitor(client_monitor(moveresize_client)); else if (focus_client) a = screen_physical_area_monitor(client_monitor(focus_client)); else { From aa329719b99792a624449b2448abee9e2c67ce94 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 16:41:52 -0500 Subject: [PATCH 19/30] Add a primaryMonitor config option, where the focus-cycle and keychain popups will appear --- data/rc.xml | 6 +++++ openbox/config.c | 13 ++++++++++ openbox/config.h | 6 +++++ openbox/focus_cycle_popup.c | 4 +-- openbox/keyboard.c | 2 +- openbox/place.c | 15 +---------- openbox/screen.c | 51 +++++++++++++++++++++++++++---------- openbox/screen.h | 14 +++++++++- 8 files changed, 80 insertions(+), 31 deletions(-) diff --git a/data/rc.xml b/data/rc.xml index d5d3eafa..8f5ee28b 100644 --- a/data/rc.xml +++ b/data/rc.xml @@ -39,6 +39,12 @@ + 1 + diff --git a/openbox/config.c b/openbox/config.c index 9b6c2028..73302dfd 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -40,6 +40,9 @@ ObPlacePolicy config_place_policy; gboolean config_place_center; ObPlaceMonitor config_place_monitor; +guint config_primary_monitor_index; +ObPlaceMonitor config_primary_monitor; + StrutPartial config_margins; gchar *config_theme; @@ -529,6 +532,13 @@ static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, else if (parse_contains("mouse", doc, n)) config_place_monitor = OB_PLACE_MONITOR_MOUSE; } + if ((n = parse_find_node("primaryMonitor", node))) { + config_primary_monitor_index = parse_int(doc, n); + if (!config_primary_monitor_index) { + if (parse_contains("mouse", doc, n)) + config_primary_monitor = OB_PLACE_MONITOR_MOUSE; + } + } } static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node, @@ -931,6 +941,9 @@ void config_startup(ObParseInst *i) config_place_center = TRUE; config_place_monitor = OB_PLACE_MONITOR_ANY; + config_primary_monitor_index = 1; + config_primary_monitor = OB_PLACE_MONITOR_ACTIVE; + parse_register(i, "placement", parse_placement, NULL); STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); diff --git a/openbox/config.h b/openbox/config.h index 69fe6ff4..33fcd684 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -83,6 +83,12 @@ extern gboolean config_place_center; already on another monitor) */ extern ObPlaceMonitor config_place_monitor; +/*! Place dialogs and stuff on this monitor. Index starts at 1. If this is + 0, then use the config_primary_monitor instead. */ +extern guint config_primary_monitor_index; +/*! Where to place dialogs and stuff if it is not specified by index. */ +extern ObPlaceMonitor config_primary_monitor; + /*! User-specified margins around the edge of the screen(s) */ extern StrutPartial config_margins; diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index 53a7eb09..a544bf14 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -261,7 +261,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) const ObFocusCyclePopupTarget *newtarget; gint newtargetx, newtargety; - screen_area = screen_physical_area_active(); + screen_area = screen_physical_area_primary(); /* get the outside margins */ RrMargins(p->a_bg, &ml, &mt, &mr, &mb); @@ -515,7 +515,7 @@ void focus_cycle_popup_single_show(struct _ObClient *c, g_assert(popup.targets == NULL); /* position the popup */ - a = screen_physical_area_active(); + a = screen_physical_area_primary(); icon_popup_position(single_popup, CenterGravity, a->x + a->width / 2, a->y + a->height / 2); icon_popup_height(single_popup, POPUP_HEIGHT); diff --git a/openbox/keyboard.c b/openbox/keyboard.c index 8c5b5543..aebee293 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -91,7 +91,7 @@ static void set_curpos(KeyBindingTree *newpos) g_free(oldtext); } - a = screen_physical_area_active(); + a = screen_physical_area_primary(); popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10); /* 1 second delay for the popup to show */ popup_delay_show(popup, G_USEC_PER_SEC, text); diff --git a/openbox/place.c b/openbox/place.c index 45d7f07f..d1d0481b 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -43,20 +43,7 @@ static void add_choice(guint *choice, guint mychoice) static Rect *pick_pointer_head(ObClient *c) { - guint i; - gint px, py; - - if (screen_pointer_pos(&px, &py)) { - for (i = 0; i < screen_num_monitors; ++i) { - Rect *monitor = screen_physical_area_monitor(i); - gboolean contain = RECT_CONTAINS(*monitor, px, py); - g_free(monitor); - if (contain) - return screen_area(c->desktop, i, NULL); - } - g_assert_not_reached(); - } else - return NULL; + return screen_area(c->desktop, screen_monitor_pointer(), NULL); } /*! Pick a monitor to place a window on. */ diff --git a/openbox/screen.c b/openbox/screen.c index 899b4bc3..bc8c72d8 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -1723,24 +1723,38 @@ gboolean screen_physical_area_monitor_contains(guint head, Rect *search) return RECT_INTERSECTS_RECT(monitor_area[head], *search); } +guint screen_monitor_active(void) +{ + if (moveresize_client) + return client_monitor(moveresize_client); + else if (focus_client) + return client_monitor(focus_client); + else + return screen_monitor_pointer(); +} + Rect* screen_physical_area_active(void) { - Rect *a; - gint x, y; + return screen_physical_area_monitor(screen_monitor_active()); +} - if (moveresize_client) - a = screen_physical_area_monitor(client_monitor(moveresize_client)); - else if (focus_client) - a = screen_physical_area_monitor(client_monitor(focus_client)); - else { - Rect mon; - if (screen_pointer_pos(&x, &y)) - RECT_SET(mon, x, y, 1, 1); +guint screen_monitor_primary(void) +{ + if (config_primary_monitor_index > 0) { + if (config_primary_monitor_index-1 < screen_num_monitors) + return config_primary_monitor_index - 1; else - RECT_SET(mon, 0, 0, 1, 1); - a = screen_physical_area_monitor(screen_find_monitor(&mon)); + return 0; } - return a; + else if (config_primary_monitor == OB_PLACE_MONITOR_ACTIVE) + return screen_monitor_active(); + else /* config_primary_monitor == OB_PLACE_MONITOR_MOUSE */ + return screen_monitor_pointer(); +} + +Rect *screen_physical_area_primary(void) +{ + return screen_physical_area_monitor(screen_monitor_primary()); } void screen_set_root_cursor(void) @@ -1753,6 +1767,17 @@ void screen_set_root_cursor(void) ob_cursor(OB_CURSOR_POINTER)); } +guint screen_monitor_pointer() +{ + Rect mon; + gint x, y; + if (screen_pointer_pos(&x, &y)) + RECT_SET(mon, x, y, 1, 1); + else + RECT_SET(mon, 0, 0, 1, 1); + return screen_find_monitor(&mon); +} + gboolean screen_pointer_pos(gint *x, gint *y) { Window w; diff --git a/openbox/screen.h b/openbox/screen.h index 39871e33..7df47f39 100644 --- a/openbox/screen.h +++ b/openbox/screen.h @@ -104,7 +104,16 @@ Rect *screen_physical_area_all_monitors(); Rect *screen_physical_area_monitor(guint head); -Rect *screen_physical_area_active(); +/*! Returns the monitor which contains the active window, or the one + containing the pointer otherwise. */ +guint screen_monitor_active(void); + +Rect *screen_physical_area_active(void); + +/*! Returns the primary monitor, as specified by the config */ +guint screen_monitor_primary(void); + +Rect *screen_physical_area_primary(void); /* doesn't include struts which the search area is already outside of when 'search' is not NULL */ @@ -133,4 +142,7 @@ void screen_set_root_cursor(); is on this screen and FALSE if it is on another screen. */ gboolean screen_pointer_pos(gint *x, gint *y); +/*! Returns the monitor which contains the pointer device */ +guint screen_monitor_pointer(void); + #endif From d3976a51fb4a43edfddf1938e249232301b9c8b5 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 17:03:27 -0500 Subject: [PATCH 20/30] Revert "Some fixes for the pager popups, and avoid a crash if you destroy a popup while it is going to be shown later by a delay." This reverts commit 33328583a143677d27eb3d081ce66532c3aaca1c. --- openbox/popup.c | 2 -- openbox/screen.c | 40 +++++++++++++++------------------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/openbox/popup.c b/openbox/popup.c index 5cbe0347..2a0d5960 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -65,8 +65,6 @@ ObPopup *popup_new(void) void popup_free(ObPopup *self) { if (self) { - popup_hide(self); /* make sure it's not showing or is being delayed and - will be shown */ XDestroyWindow(ob_display, self->bg); XDestroyWindow(ob_display, self->text); RrAppearanceFree(self->a_bg); diff --git a/openbox/screen.c b/openbox/screen.c index bc8c72d8..b16bb17b 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -57,7 +57,7 @@ static void screen_tell_ksplash(void); static void screen_fallback_focus(void); guint screen_num_desktops; -guint screen_num_monitors = 0; +guint screen_num_monitors; guint screen_desktop; guint screen_last_desktop; gboolean screen_showing_desktop; @@ -77,7 +77,7 @@ static GSList *struts_left = NULL; static GSList *struts_right = NULL; static GSList *struts_bottom = NULL; -static ObPagerPopup **desktop_popup = NULL; +static ObPagerPopup **desktop_popup; /*! The number of microseconds that you need to be on a desktop before it will replace the remembered "last desktop" */ @@ -355,19 +355,20 @@ void screen_startup(gboolean reconfig) if (reconfig) { guint i; - - /* recreate the pager popups to use any new theme stuff. it was - freed in screen_shutdown() already. */ desktop_popup = g_new(ObPagerPopup*, screen_num_monitors); for (i = 0; i < screen_num_monitors; i++) { desktop_popup[i] = pager_popup_new(); pager_popup_height(desktop_popup[i], POPUP_HEIGHT); + + /* update the pager popup's width */ pager_popup_text_width_to_strings(desktop_popup[i], screen_desktop_names, screen_num_desktops); } return; + } else { + desktop_popup = NULL; } /* get the initial size */ @@ -459,10 +460,10 @@ void screen_shutdown(gboolean reconfig) { guint i; - for (i = 0; i < screen_num_monitors; i++) + for (i = 0; i < screen_num_monitors; i++) { pager_popup_free(desktop_popup[i]); + } g_free(desktop_popup); - desktop_popup = NULL; if (reconfig) return; @@ -509,7 +510,6 @@ void screen_resize(void) screen_update_areas(); dock_configure(); - /* make sure all windows are visible */ for (it = client_list; it; it = g_list_next(it)) client_move_onscreen(it->data, FALSE); } @@ -1349,32 +1349,22 @@ typedef struct { void screen_update_areas(void) { - guint i, j, onum; + guint i, j; gulong *dims; GList *it; GSList *sit; - onum = screen_num_monitors; - g_free(monitor_area); extensions_xinerama_screens(&monitor_area, &screen_num_monitors); - if (screen_num_monitors < onum) { - /* free some of the pager popups */ - for (i = screen_num_monitors; i < onum; ++i) - pager_popup_free(desktop_popup[i]); - desktop_popup = g_renew(ObPagerPopup*, desktop_popup, - screen_num_monitors); - } - else { - /* add some more pager popups */ - desktop_popup = g_renew(ObPagerPopup*, desktop_popup, - screen_num_monitors); - for (i = onum; i < screen_num_monitors; ++i) { + if (!desktop_popup) { + desktop_popup = g_new(ObPagerPopup*, screen_num_monitors); + for (i = 0; i < screen_num_monitors; i++) { desktop_popup[i] = pager_popup_new(); pager_popup_height(desktop_popup[i], POPUP_HEIGHT); - if (screen_desktop_names) /* the areas are initialized before the - desktop names */ + + if (screen_desktop_names) + /* update the pager popup's width */ pager_popup_text_width_to_strings(desktop_popup[i], screen_desktop_names, screen_num_desktops); From 5f2182c33ba5e716885f096bfe498620d111908c Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 17:03:37 -0500 Subject: [PATCH 21/30] Revert "Show desktop switch popup on every monitor" This reverts commit 2e1adce628ee3234accc5d88cafb57672800cae0. --- openbox/screen.c | 101 ++++++++++++++--------------------------------- 1 file changed, 30 insertions(+), 71 deletions(-) diff --git a/openbox/screen.c b/openbox/screen.c index b16bb17b..cf2a6db7 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -77,7 +77,7 @@ static GSList *struts_left = NULL; static GSList *struts_right = NULL; static GSList *struts_bottom = NULL; -static ObPagerPopup **desktop_popup; +static ObPagerPopup *desktop_popup; /*! The number of microseconds that you need to be on a desktop before it will replace the remembered "last desktop" */ @@ -353,22 +353,15 @@ void screen_startup(gboolean reconfig) guint32 d; gboolean namesexist = FALSE; + desktop_popup = pager_popup_new(); + pager_popup_height(desktop_popup, POPUP_HEIGHT); + if (reconfig) { - guint i; - desktop_popup = g_new(ObPagerPopup*, screen_num_monitors); - for (i = 0; i < screen_num_monitors; i++) { - desktop_popup[i] = pager_popup_new(); - pager_popup_height(desktop_popup[i], POPUP_HEIGHT); - - /* update the pager popup's width */ - pager_popup_text_width_to_strings(desktop_popup[i], - screen_desktop_names, - screen_num_desktops); - } - + /* update the pager popup's width */ + pager_popup_text_width_to_strings(desktop_popup, + screen_desktop_names, + screen_num_desktops); return; - } else { - desktop_popup = NULL; } /* get the initial size */ @@ -458,12 +451,7 @@ void screen_startup(gboolean reconfig) void screen_shutdown(gboolean reconfig) { - guint i; - - for (i = 0; i < screen_num_monitors; i++) { - pager_popup_free(desktop_popup[i]); - } - g_free(desktop_popup); + pager_popup_free(desktop_popup); if (reconfig) return; @@ -943,52 +931,39 @@ static guint translate_row_col(guint r, guint c) static gboolean hide_desktop_popup_func(gpointer data) { - guint i; - - for (i = 0; i < screen_num_monitors; i++) { - pager_popup_hide(desktop_popup[i]); - } + pager_popup_hide(desktop_popup); return FALSE; /* don't repeat */ } void screen_show_desktop_popup(guint d) { Rect *a; - guint i; /* 0 means don't show the popup */ if (!config_desktop_popup_time) return; - for (i = 0; i < screen_num_monitors; i++) { - a = screen_physical_area_monitor(i); - pager_popup_position(desktop_popup[i], CenterGravity, - a->x + a->width / 2, a->y + a->height / 2); - pager_popup_icon_size_multiplier(desktop_popup[i], - (screen_desktop_layout.columns / - screen_desktop_layout.rows) / 2, - (screen_desktop_layout.rows/ - screen_desktop_layout.columns) / 2); - pager_popup_max_width(desktop_popup[i], - MAX(a->width/3, POPUP_WIDTH)); - pager_popup_show(desktop_popup[i], screen_desktop_names[d], d); + a = screen_physical_area_active(); + pager_popup_position(desktop_popup, CenterGravity, + a->x + a->width / 2, a->y + a->height / 2); + pager_popup_icon_size_multiplier(desktop_popup, + (screen_desktop_layout.columns / + screen_desktop_layout.rows) / 2, + (screen_desktop_layout.rows/ + screen_desktop_layout.columns) / 2); + pager_popup_max_width(desktop_popup, + MAX(a->width/3, POPUP_WIDTH)); + pager_popup_show(desktop_popup, screen_desktop_names[d], d); - ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); - ob_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000, - hide_desktop_popup_func, desktop_popup[i], - g_direct_equal, NULL); - g_free(a); - } + ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); + ob_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000, + hide_desktop_popup_func, NULL, NULL, NULL); + g_free(a); } void screen_hide_desktop_popup(void) { - guint i; - - for (i = 0; i < screen_num_monitors; i++) { - ob_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func, - desktop_popup[i], FALSE); - pager_popup_hide(desktop_popup[i]); - } + ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); + pager_popup_hide(desktop_popup); } guint screen_find_desktop(guint from, ObDirection dir, @@ -1223,11 +1198,9 @@ void screen_update_desktop_names(void) } /* resize the pager for these names */ - for (i = 0; i < screen_num_monitors; i++) { - pager_popup_text_width_to_strings(desktop_popup[i], - screen_desktop_names, - screen_num_desktops); - } + pager_popup_text_width_to_strings(desktop_popup, + screen_desktop_names, + screen_num_desktops); } void screen_show_desktop(gboolean show, ObClient *show_only) @@ -1357,20 +1330,6 @@ void screen_update_areas(void) g_free(monitor_area); extensions_xinerama_screens(&monitor_area, &screen_num_monitors); - if (!desktop_popup) { - desktop_popup = g_new(ObPagerPopup*, screen_num_monitors); - for (i = 0; i < screen_num_monitors; i++) { - desktop_popup[i] = pager_popup_new(); - pager_popup_height(desktop_popup[i], POPUP_HEIGHT); - - if (screen_desktop_names) - /* update the pager popup's width */ - pager_popup_text_width_to_strings(desktop_popup[i], - screen_desktop_names, - screen_num_desktops); - } - } - /* set up the user-specified margins */ config_margins.top_start = RECT_LEFT(monitor_area[screen_num_monitors]); config_margins.top_end = RECT_RIGHT(monitor_area[screen_num_monitors]); From 81eb4752fe13e05d4bef2eef322617f1a7d4029f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Wed, 9 Dec 2009 17:03:51 -0500 Subject: [PATCH 22/30] Make the desktop popup show on the primary monitor as defined in the config. This matches the behaviour of the focus cycle and key chain popups. --- openbox/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openbox/screen.c b/openbox/screen.c index cf2a6db7..4412027e 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -942,7 +942,7 @@ void screen_show_desktop_popup(guint d) /* 0 means don't show the popup */ if (!config_desktop_popup_time) return; - a = screen_physical_area_active(); + a = screen_physical_area_primary(); pager_popup_position(desktop_popup, CenterGravity, a->x + a->width / 2, a->y + a->height / 2); pager_popup_icon_size_multiplier(desktop_popup, From 7abc28bdda2503732d3ee26192454f5058c84b83 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Thu, 10 Dec 2009 09:40:20 -0500 Subject: [PATCH 23/30] Fix a typo in xdg-autostart --- tools/xdg-autostart/xdg-autostart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/xdg-autostart/xdg-autostart b/tools/xdg-autostart/xdg-autostart index 64f26dc8..4a533826 100755 --- a/tools/xdg-autostart/xdg-autostart +++ b/tools/xdg-autostart/xdg-autostart @@ -80,7 +80,7 @@ class AutostartFile: def __str__(self): return self.path + " : " + self.de.getName() - def _isexecfile(path): + def _isexecfile(self, path): return os.access(path, os.X_OK) def _findFile(self, path, search, match_func): From f0df9bb9d8f4f8182e60996d92a7b0e47549a0f6 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 10:07:50 -0500 Subject: [PATCH 24/30] Remove desktop hints since Openbox won't overwrite them, but they may be set from GDM or other sessions --- data/xsession/openbox-gnome-session.in | 5 +++++ data/xsession/openbox-kde-session.in | 5 +++++ data/xsession/openbox-session.in | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/data/xsession/openbox-gnome-session.in b/data/xsession/openbox-gnome-session.in index d93bab0c..86b7d06f 100644 --- a/data/xsession/openbox-gnome-session.in +++ b/data/xsession/openbox-gnome-session.in @@ -7,6 +7,11 @@ if test -n "$1"; then exit fi +# Clean up after GDM +xprop -root -remove _NET_NUMBER_OF_DESKTOPS \ + -remove _NET_DESKTOP_NAMES \ + -remove _NET_CURRENT_DESKTOP 2> /dev/null + VER=$(gnome-session --version 2>/dev/null | \ sed -e 's/[^0-9.]*\([0-9.]\+\)/\1/') diff --git a/data/xsession/openbox-kde-session.in b/data/xsession/openbox-kde-session.in index 16017260..5299b045 100644 --- a/data/xsession/openbox-kde-session.in +++ b/data/xsession/openbox-kde-session.in @@ -7,6 +7,11 @@ if test -n "$1"; then exit fi +# Clean up after GDM +xprop -root -remove _NET_NUMBER_OF_DESKTOPS \ + -remove _NET_DESKTOP_NAMES \ + -remove _NET_CURRENT_DESKTOP 2> /dev/null + # Run KDE with Openbox as its window manager export KDEWM="@bindir@/openbox" exec startkde "$@" diff --git a/data/xsession/openbox-session.in b/data/xsession/openbox-session.in index 7c3daa73..fa1bb996 100644 --- a/data/xsession/openbox-session.in +++ b/data/xsession/openbox-session.in @@ -7,6 +7,11 @@ if test -n "$1"; then exit fi +# Clean up after GDM +xprop -root -remove _NET_NUMBER_OF_DESKTOPS \ + -remove _NET_DESKTOP_NAMES \ + -remove _NET_CURRENT_DESKTOP 2> /dev/null + AUTOSTART="${XDG_CONFIG_HOME:-"$HOME/.config"}/openbox/autostart.sh" GLOBALAUTOSTART="@configdir@/openbox/autostart.sh" From d17bc61b2434838c2105bf5c5012bcf4e404f6b1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 10:10:03 -0500 Subject: [PATCH 25/30] Don't need 2 exit actions in the default menu now, they both would do the same thing --- data/menu.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/data/menu.xml b/data/menu.xml index 61fba664..39da04d6 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -369,11 +369,6 @@ - - - yes - - @@ -390,7 +385,7 @@ - + yes From c5155e7422668f6a176c15f2cecac6693fcf3134 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 10:27:54 -0500 Subject: [PATCH 26/30] Add an openbox.desktop file for the applications/ directory This is for gnome-session to start Openbox correctly as the window manager See the commit log for http://cvs.fedoraproject.org/viewvc/devel/openbox/openbox.desktop?revision=1.3&view=markup --- Makefile.am | 4 ++++ data/openbox.desktop | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 data/openbox.desktop diff --git a/Makefile.am b/Makefile.am index 5c312c72..660b5ef5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,7 @@ pubincludedir = $(includedir)/openbox/@OB_VERSION@/openbox pixmapdir = $(datadir)/pixmaps xsddir = $(datadir)/openbox secretbindir = $(libdir)/openbox +appsdir = $(datadir)/applications theme = Clearlooks @@ -414,6 +415,9 @@ nodist_pkgconfig_DATA = \ ## data ## +dist_apps_DATA = \ + data/openbox.desktop + dist_pixmap_DATA = \ data/openbox.png diff --git a/data/openbox.desktop b/data/openbox.desktop new file mode 100644 index 00000000..9c19e67e --- /dev/null +++ b/data/openbox.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +Encoding=UTF-8 +Name=Openbox +Exec=openbox +Icon=openbox +NoDisplay=true +# name we put on the WM spec check window +X-GNOME-WMName=Openbox +X-GNOME-Autostart-Phase=WindowManager +X-GNOME-Provides=windowmanager +X-GNOME-Autostart-Notify=true From 231f694bcab8eb4ac3b5221191b362b35eddd326 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 10:36:19 -0500 Subject: [PATCH 27/30] Make sure popup dialogs are not waiting to be shown after they are freed --- openbox/popup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openbox/popup.c b/openbox/popup.c index 2a0d5960..5cbe0347 100644 --- a/openbox/popup.c +++ b/openbox/popup.c @@ -65,6 +65,8 @@ ObPopup *popup_new(void) void popup_free(ObPopup *self) { if (self) { + popup_hide(self); /* make sure it's not showing or is being delayed and + will be shown */ XDestroyWindow(ob_display, self->bg); XDestroyWindow(ob_display, self->text); RrAppearanceFree(self->a_bg); From 7e6ef2683f68d0b8cf75d4ebb6a778cd87288d7f Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 11:44:28 -0500 Subject: [PATCH 28/30] Run Openbox with gnome-session the proper way, without using the deprecated gnome-wm. See https://bugzilla.gnome.org/show_bug.cgi?id=555406#c5 Hopefully this continues to work for a while. --- data/xsession/openbox-gnome-session.in | 40 ++++++++++++++++++++------ 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/data/xsession/openbox-gnome-session.in b/data/xsession/openbox-gnome-session.in index 86b7d06f..de46bec5 100644 --- a/data/xsession/openbox-gnome-session.in +++ b/data/xsession/openbox-gnome-session.in @@ -18,20 +18,42 @@ VER=$(gnome-session --version 2>/dev/null | \ MAJOR=$(echo $VER | cut -d . -f 1) MINOR=$(echo $VER | cut -d . -f 2) -# Run GNOME with Openbox as its window manager -export WINDOW_MANAGER="@bindir@/openbox" +# run GNOME with Openbox as its window manager if test $MAJOR -lt 2 || (test $MAJOR = 2 && test $MINOR -le 22); then - # old gnome-session allows multiple sessions to be saved + # old gnome-session was easy to work with + export WINDOW_MANAGER="@bindir@/openbox" exec gnome-session --choose-session=openbox-session "$@" else - # make sure the gnome-wm script is being used - gconftool-2 -t string \ - -s /desktop/gnome/session/required_components/windowmanager "gnome-wm" \ - 2> /dev/null + # new gnome-session requires openbox to be set in gconf and an + # openbox.desktop to be installed in the applications directory - # new gnome-session does not allow multiple sessions - exec gnome-session "$@" + SPATH=/desktop/gnome/session + + # get the current default session + SESSION=$(gconftool-2 -g $SPATH/default_session 2> /dev/null) + + # make sure openbox is going to be run + if test -z "$SESSION"; then + # if its empty then just run openbox + SESSION="[openbox]" + elif test -z $(echo "$SESSION" | grep -q openbox); then + # if openbox isn't in the session then append it + SESSION="${SESSION%]},openbox]" + fi + + # get the current GNOME/Openbox session + OB_SESSION=$(gconftool-2 -g $SPATH/openbox_session 2> /dev/null) + + # update the GNOME/Openbox session if needed + if x$OB_SESSION != x$SESSION; then + # the default session changed or we didn't run GNOME/Openbox before + gconftool-2 -t list --list-type=strings -s $SPATH/openbox_session \ + "$SESSION" 2> /dev/null + fi + + # run GNOME/Openbox + exec gnome-session --default-session-key $SPATH/openbox_session "$@" fi From 5c01dc651a220ad1ccce9502da577d81f1877388 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 10 Dec 2009 15:00:56 -0500 Subject: [PATCH 29/30] Get the session client id from new gnome-session See http://live.gnome.org/SessionManagement/GnomeSession#A1._Launch Gnome-session sets the DESKTOP_AUTOSTART_ID env variable with the SM client id instead of passing it on the command line. --- openbox/openbox.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openbox/openbox.c b/openbox/openbox.c index 4a49c802..60e147c3 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -561,8 +561,21 @@ static void remove_args(gint *argc, gchar **argv, gint index, gint num) static void parse_env() { + const gchar *id; + /* unset this so we don't pass it on unknowingly */ unsetenv("DESKTOP_STARTUP_ID"); + + /* this is how gnome-session passes in a session client id */ + id = g_getenv("DESKTOP_AUTOSTART_ID"); + if (id) { + unsetenv("DESKTOP_AUTOSTART_ID"); + if (ob_sm_id) g_free(ob_sm_id); + ob_sm_id = g_strdup(id); + ob_debug_type(OB_DEBUG_SM, + "DESKTOP_AUTOSTART_ID %s supercedes --sm-client-id\n", + ob_sm_id); + } } static void parse_args(gint *argc, gchar **argv) From 9ba2b04e96449fea5b6bd212aa3d431638754bdd Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 11 Dec 2009 18:27:46 -0500 Subject: [PATCH 30/30] Set hints that remember the WM_WINDOW_ROLE and WM_CLASS properties for our users. The hints are _OB_ROLE, _OB_NAME, and _OB_CLASS. --- openbox/client.c | 11 +++++++++++ openbox/prop.c | 3 +++ openbox/prop.h | 3 +++ openbox/screen.c | 3 +++ 4 files changed, 20 insertions(+) diff --git a/openbox/client.c b/openbox/client.c index fcbe7cd9..e3a7d6ec 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -76,6 +76,7 @@ static RrImage *client_default_icon = NULL; static void client_get_all(ObClient *self, gboolean real); static void client_get_startup_id(ObClient *self); static void client_get_session_ids(ObClient *self); +static void client_save_session_ids(ObClient *self); static void client_get_area(ObClient *self); static void client_get_desktop(ObClient *self); static void client_get_state(ObClient *self); @@ -1159,6 +1160,7 @@ static void client_get_all(ObClient *self, gboolean real) /* get the session related properties, these can change decorations from per-app settings */ client_get_session_ids(self); + client_save_session_ids(self); /* now we got everything that can affect the decorations */ if (!real) @@ -2367,6 +2369,15 @@ static void client_get_session_ids(ObClient *self) } } +/*! Save the session IDs as seen by Openbox when the window mapped, so that + users can still access them later if the app changes them */ +static void client_save_session_ids(ObClient *self) +{ + PROP_SETS(self->window, ob_role, self->role); + PROP_SETS(self->window, ob_name, self->name); + PROP_SETS(self->window, ob_class, self->class); +} + static void client_change_wm_state(ObClient *self) { gulong state[2]; diff --git a/openbox/prop.c b/openbox/prop.c index ec1ce3db..b21b3f53 100644 --- a/openbox/prop.c +++ b/openbox/prop.c @@ -179,6 +179,9 @@ void prop_startup(void) CREATE(ob_wm_action_undecorate, "_OB_WM_ACTION_UNDECORATE"); CREATE(ob_wm_state_undecorated, "_OB_WM_STATE_UNDECORATED"); CREATE(ob_control, "_OB_CONTROL"); + CREATE(ob_role, "_OB_ROLE"); + CREATE(ob_name, "_OB_NAME"); + CREATE(ob_class, "_OB_CLASS"); } #include diff --git a/openbox/prop.h b/openbox/prop.h index 644717a2..419aa512 100644 --- a/openbox/prop.h +++ b/openbox/prop.h @@ -202,6 +202,9 @@ typedef struct Atoms { Atom ob_theme; Atom ob_config_file; Atom ob_control; + Atom ob_role; + Atom ob_name; + Atom ob_class; } Atoms; extern Atoms prop_atoms; diff --git a/openbox/screen.c b/openbox/screen.c index 4412027e..8d0460d5 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -302,6 +302,9 @@ gboolean screen_annex(void) supported[i++] = prop_atoms.ob_theme; supported[i++] = prop_atoms.ob_config_file; supported[i++] = prop_atoms.ob_control; + supported[i++] = prop_atoms.ob_role; + supported[i++] = prop_atoms.ob_name; + supported[i++] = prop_atoms.ob_class; g_assert(i == num_support); PROP_SETA32(RootWindow(ob_display, ob_screen),