diff options
| author | Dana Jansens <danakj@orodu.net> | 2009-12-11 19:02:11 -0500 |
|---|---|---|
| committer | Dana Jansens <danakj@orodu.net> | 2009-12-11 19:02:11 -0500 |
| commit | acafa38c8ea210b12ed92fc16281b915ab61542c (patch) | |
| tree | ce4c7d2a4a9b3478a4d48af2c54ada06593ed022 /openbox | |
| parent | 2f09e0ce388f63c341cb328d795766e2bd0dc24b (diff) | |
| parent | 9ba2b04e96449fea5b6bd212aa3d431638754bdd (diff) | |
Merge branch 'backport' into work
Conflicts:
openbox/config.c
openbox/event.c
openbox/prop.c
openbox/prop.h
openbox/screen.c
openbox/screen.h
Diffstat (limited to 'openbox')
| -rw-r--r-- | openbox/actions/focus.c | 3 | ||||
| -rw-r--r-- | openbox/client.c | 56 | ||||
| -rw-r--r-- | openbox/client.h | 7 | ||||
| -rw-r--r-- | openbox/client_list_combined_menu.c | 2 | ||||
| -rw-r--r-- | openbox/client_list_menu.c | 2 | ||||
| -rw-r--r-- | openbox/config.c | 20 | ||||
| -rw-r--r-- | openbox/config.h | 6 | ||||
| -rw-r--r-- | openbox/event.c | 4 | ||||
| -rw-r--r-- | openbox/focus.c | 22 | ||||
| -rw-r--r-- | openbox/focus.h | 3 | ||||
| -rw-r--r-- | openbox/focus_cycle.c | 10 | ||||
| -rw-r--r-- | openbox/focus_cycle_popup.c | 7 | ||||
| -rw-r--r-- | openbox/frame.c | 7 | ||||
| -rw-r--r-- | openbox/keyboard.c | 2 | ||||
| -rw-r--r-- | openbox/openbox.c | 13 | ||||
| -rw-r--r-- | openbox/place.c | 15 | ||||
| -rw-r--r-- | openbox/screen.c | 182 | ||||
| -rw-r--r-- | openbox/screen.h | 12 | ||||
| -rw-r--r-- | openbox/stacking.c | 17 |
19 files changed, 223 insertions, 167 deletions
diff --git a/openbox/actions/focus.c b/openbox/actions/focus.c index 4d0f220d..e25a79ea 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; @@ -44,7 +45,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 50a0dbee..184ae171 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -75,6 +75,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); @@ -289,7 +290,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; } @@ -1075,6 +1077,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) @@ -2031,7 +2034,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 @@ -2288,6 +2291,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) +{ + OBT_PROP_SETS(self->window, OB_ROLE, utf8, self->role); + OBT_PROP_SETS(self->window, OB_NAME, utf8, self->name); + OBT_PROP_SETS(self->window, OB_CLASS, utf8, self->class); +} + static void client_change_wm_state(ObClient *self) { gulong state[2]; @@ -3817,7 +3829,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 || @@ -3825,7 +3838,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); @@ -4122,39 +4135,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(); @@ -4163,6 +4163,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; @@ -4184,7 +4193,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, diff --git a/openbox/client.h b/openbox/client.h index 30cab17b..8126abe2 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -575,13 +575,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/config.c b/openbox/config.c index 5c0691ca..0d28be2c 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -39,6 +39,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; @@ -437,8 +440,13 @@ static void parse_mouse(xmlNodePtr node, gpointer d) config_mouse_threshold = obt_parse_node_int(n); if ((n = obt_parse_find_node(node, "doubleClickTime"))) config_mouse_dclicktime = obt_parse_node_int(n); - if ((n = obt_parse_find_node(node, "screenEdgeWarpTime"))) + if ((n = obt_parse_find_node(node, "screenEdgeWarpTime"))) { config_mouse_screenedgetime = obt_parse_node_int(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 = obt_parse_find_node(node, "context"); while (n) { @@ -515,6 +523,13 @@ static void parse_placement(xmlNodePtr node, gpointer d) else if (obt_parse_node_contains(n, "mouse")) config_place_monitor = OB_PLACE_MONITOR_MOUSE; } + if ((n = obt_parse_find_node(node, "primaryMonitor"))) { + config_primary_monitor_index = obt_parse_node_int(n); + if (!config_primary_monitor_index) { + if (obt_parse_node_contains(n, "mouse")) + config_primary_monitor = OB_PLACE_MONITOR_MOUSE; + } + } } static void parse_margins(xmlNodePtr node, gpointer d) @@ -918,6 +933,9 @@ void config_startup(ObtParseInst *i) config_place_center = TRUE; config_place_monitor = OB_PLACE_MONITOR_ANY; + config_primary_monitor_index = 1; + config_primary_monitor = OB_PLACE_MONITOR_ACTIVE; + obt_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 248f97b3..d9e897a1 100644 --- a/openbox/config.h +++ b/openbox/config.h @@ -82,6 +82,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/event.c b/openbox/event.c index 4ddb7ac7..04c6a7c6 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -1282,7 +1282,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 */ @@ -1338,7 +1338,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", 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 == OBT_PROP_ATOM(NET_WM_MOVERESIZE)) { diff --git a/openbox/focus.c b/openbox/focus.c index fc0fd99b..a75c170f 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -129,7 +129,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)) @@ -149,7 +149,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)) { @@ -183,12 +183,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); @@ -280,7 +274,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; } @@ -293,7 +287,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; @@ -332,9 +327,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), @@ -347,7 +344,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 4f37b728..80ce3a38 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 063de644..d5654b3d 100644 --- a/openbox/focus_cycle.c +++ b/openbox/focus_cycle.c @@ -59,7 +59,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); @@ -121,7 +122,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 */ @@ -188,7 +190,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 @@ -296,7 +298,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 a60534ad..2ad786c0 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -263,7 +263,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); @@ -350,7 +351,7 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) g_assert(mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS || mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST); - screen_area = screen_physical_area_active(); + screen_area = screen_physical_area_primary(); /* get the outside margins */ RrMargins(p->a_bg, &ml, &mt, &mr, &mb); @@ -714,7 +715,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/frame.c b/openbox/frame.c index 72eab32b..6387d7ef 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -21,6 +21,7 @@ #include "client.h" #include "openbox.h" #include "grab.h" +#include "debug.h" #include "config.h" #include "framerender.h" #include "focus_cycle.h" @@ -368,8 +369,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)); @@ -948,6 +948,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); diff --git a/openbox/keyboard.c b/openbox/keyboard.c index 410eb6e0..ade18d04 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -89,7 +89,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/openbox.c b/openbox/openbox.c index e912c64c..29506c00 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -546,8 +546,21 @@ static void remove_args(gint *argc, gchar **argv, gint index, gint num) static void parse_env(void) { + 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) diff --git a/openbox/place.c b/openbox/place.c index aac40e8a..ee8bf7eb 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 b53671fa..8012942b 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -56,7 +56,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; @@ -76,7 +76,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" */ @@ -292,6 +292,9 @@ gboolean screen_annex(void) supported[i++] = OBT_PROP_ATOM(OB_THEME); supported[i++] = OBT_PROP_ATOM(OB_CONFIG_FILE); supported[i++] = OBT_PROP_ATOM(OB_CONTROL); + supported[i++] = OBT_PROP_ATOM(OB_ROLE); + supported[i++] = OBT_PROP_ATOM(OB_NAME); + supported[i++] = OBT_PROP_ATOM(OB_CLASS); g_assert(i == num_support); OBT_PROP_SETA32(obt_root(ob_screen), @@ -343,20 +346,14 @@ void screen_startup(gboolean reconfig) guint32 d; gboolean namesexist = FALSE; - 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); - pager_popup_text_width_to_strings(desktop_popup[i], - screen_desktop_names, - screen_num_desktops); - } + desktop_popup = pager_popup_new(); + pager_popup_height(desktop_popup, POPUP_HEIGHT); + if (reconfig) { + /* update the pager popup's width */ + pager_popup_text_width_to_strings(desktop_popup, + screen_desktop_names, + screen_num_desktops); return; } @@ -446,12 +443,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); - desktop_popup = NULL; + pager_popup_free(desktop_popup); if (reconfig) return; @@ -497,7 +489,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); } @@ -711,6 +702,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); + } } } @@ -918,52 +918,41 @@ 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); - - obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); - obt_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); - } + 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, + (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); + + obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func); + obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000, + hide_desktop_popup_func, desktop_popup, + g_direct_equal, NULL); + g_free(a); } void screen_hide_desktop_popup(void) { - guint i; - - for (i = 0; i < screen_num_monitors; i++) { - obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func, - desktop_popup[i], FALSE); - pager_popup_hide(desktop_popup[i]); - } + obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func, + desktop_popup, FALSE); + pager_popup_hide(desktop_popup); } guint screen_find_desktop(guint from, ObDirection dir, @@ -1198,11 +1187,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) @@ -1372,38 +1359,14 @@ static void get_xinerama_screens(Rect **xin_areas, guint *nxin) 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); get_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) { - 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 */ - 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]); @@ -1746,24 +1709,38 @@ gboolean screen_physical_area_monitor_contains(guint head, Rect *search) return RECT_INTERSECTS_RECT(monitor_area[head], *search); } -Rect* screen_physical_area_active(void) +guint screen_monitor_active(void) { - Rect *a; - gint x, y; - if (moveresize_client) - a = screen_physical_area_monitor(client_monitor(focus_client)); + return 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); + return client_monitor(focus_client); + else + return screen_monitor_pointer(); +} + +Rect* screen_physical_area_active(void) +{ + return screen_physical_area_monitor(screen_monitor_active()); +} + +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) @@ -1776,6 +1753,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 11915f11..1479db16 100644 --- a/openbox/screen.h +++ b/openbox/screen.h @@ -104,8 +104,17 @@ Rect *screen_physical_area_all_monitors(void); Rect *screen_physical_area_monitor(guint head); +/*! 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 */ #define SCREEN_AREA_ALL_MONITORS ((unsigned)-1) @@ -133,4 +142,7 @@ void screen_set_root_cursor(void); 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 diff --git a/openbox/stacking.c b/openbox/stacking.c index 2a34f71d..cb710e5e 100644 --- a/openbox/stacking.c +++ b/openbox/stacking.c @@ -218,6 +218,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; @@ -248,6 +249,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)) { @@ -256,6 +259,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); @@ -268,8 +278,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 */ |
