summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2009-12-11 19:02:11 -0500
committerDana Jansens <danakj@orodu.net>2009-12-11 19:02:11 -0500
commitacafa38c8ea210b12ed92fc16281b915ab61542c (patch)
treece4c7d2a4a9b3478a4d48af2c54ada06593ed022 /openbox
parent2f09e0ce388f63c341cb328d795766e2bd0dc24b (diff)
parent9ba2b04e96449fea5b6bd212aa3d431638754bdd (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.c3
-rw-r--r--openbox/client.c56
-rw-r--r--openbox/client.h7
-rw-r--r--openbox/client_list_combined_menu.c2
-rw-r--r--openbox/client_list_menu.c2
-rw-r--r--openbox/config.c20
-rw-r--r--openbox/config.h6
-rw-r--r--openbox/event.c4
-rw-r--r--openbox/focus.c22
-rw-r--r--openbox/focus.h3
-rw-r--r--openbox/focus_cycle.c10
-rw-r--r--openbox/focus_cycle_popup.c7
-rw-r--r--openbox/frame.c7
-rw-r--r--openbox/keyboard.c2
-rw-r--r--openbox/openbox.c13
-rw-r--r--openbox/place.c15
-rw-r--r--openbox/screen.c182
-rw-r--r--openbox/screen.h12
-rw-r--r--openbox/stacking.c17
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 */