Add a primaryMonitor config option, where the focus-cycle and keychain popups will...
authorDana Jansens <danakj@orodu.net>
Wed, 9 Dec 2009 21:41:52 +0000 (16:41 -0500)
committerDana Jansens <danakj@orodu.net>
Wed, 9 Dec 2009 21:41:52 +0000 (16:41 -0500)
data/rc.xml
openbox/config.c
openbox/config.h
openbox/focus_cycle_popup.c
openbox/keyboard.c
openbox/place.c
openbox/screen.c
openbox/screen.h

index d5d3eaf..8f5ee28 100644 (file)
   <!-- with Smart placement on a multi-monitor system, try to place new windows
        on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
        the active window is -->
+  <primaryMonitor>1</primaryMonitor>
+  <!-- The monitor where Openbox should place popup dialogs such as the
+       focus cycling popup, or the desktop switch popup.  It can be an index
+       from 1, specifying a particular monitor.  Or it can be one of the
+       following: 'Mouse' - where the mouse is, or
+                  'Active' - where the active window is -->
 </placement>
 
 <theme>
index 9b6c202..73302df 100644 (file)
@@ -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);
index 69fe6ff..33fcd68 100644 (file)
@@ -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;
 
index 53a7eb0..a544bf1 100644 (file)
@@ -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);
index 8c5b554..aebee29 100644 (file)
@@ -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);
index 45d7f07..d1d0481 100644 (file)
@@ -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. */
index 899b4bc..bc8c72d 100644 (file)
@@ -1723,24 +1723,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(moveresize_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)
@@ -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;
index 39871e3..7df47f3 100644 (file)
@@ -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