From 4aade63604e9d29f01933b9bf0ac9228721411ef Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 14 Oct 2011 19:24:45 -0400 Subject: [PATCH] Allow per-app settings to pick a monitor for a window without choosing a position in it. --- openbox/config.c | 4 +-- openbox/place.c | 91 +++++++++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/openbox/config.c b/openbox/config.c index 857255fa..9067011a 100644 --- a/openbox/config.c +++ b/openbox/config.c @@ -291,8 +291,8 @@ static void parse_per_app_settings(xmlNodePtr node, gpointer d) settings->pos_given = TRUE; } - if (settings->pos_given && - (c = obt_xml_find_node(n->children, "monitor"))) + /* monitor can be set without setting x or y */ + if ((c = obt_xml_find_node(n->children, "monitor"))) if (!obt_xml_node_contains(c, "default")) { gchar *s = obt_xml_node_string(c); if (!g_ascii_strcasecmp(s, "mouse")) diff --git a/openbox/place.c b/openbox/place.c index 8a4a4264..a73a8bfb 100644 --- a/openbox/place.c +++ b/openbox/place.c @@ -37,27 +37,29 @@ static Rect *pick_pointer_head(ObClient *c) When a window is being placed in the FOREGROUND, use a monitor chosen in the following order: - 1. same monitor as parent - 2. primary monitor if placement=PRIMARY + 1. per-app settings + 2. same monitor as parent + 3. primary monitor if placement=PRIMARY active monitor if placement=ACTIVE pointer monitor if placement=MOUSE - 3. primary monitor - 4. other monitors where the window has group members on the same desktop - 5. other monitors where the window has group members on other desktops - 6. other monitors + 4. primary monitor + 5. other monitors where the window has group members on the same desktop + 6. other monitors where the window has group members on other desktops + 7. other monitors When a window is being placed in the BACKGROUND, use a monitor chosen in the following order: - 1. same monitor as parent - 2. other monitors where the window has group members on the same desktop - 2a. primary monitor in this set - 2b. other monitors in this set - 3. other monitors where the window has group members on other desktops + 1. per-app settings + 2. same monitor as parent + 3. other monitors where the window has group members on the same desktop 3a. primary monitor in this set 3b. other monitors in this set - 4. other monitors + 4. other monitors where the window has group members on other desktops 4a. primary monitor in this set 4b. other monitors in this set + 5. other monitors + 5a. primary monitor in this set + 5b. other monitors in this set */ /*! One for each possible head, used to sort them in order of precedence. */ @@ -73,6 +75,7 @@ enum { HEAD_PRIMARY = 1 << 2, /* primary monitor */ HEAD_GROUP_DESK = 1 << 3, /* has a group member on the same desktop */ HEAD_GROUP = 1 << 4, /* has a group member on another desktop */ + HEAD_PERAPP = 1 << 5, /* chosen by per-app settings */ }; gint cmp_foreground(const void *a, const void *b) @@ -83,6 +86,10 @@ gint cmp_foreground(const void *a, const void *b) if (h1->monitor == h2->monitor) return 0; + if (h1->flags & HEAD_PERAPP) --i; + if (h2->flags & HEAD_PERAPP) ++i; + if (i) return i; + if (h1->flags & HEAD_PARENT) --i; if (h2->flags & HEAD_PARENT) ++i; if (i) return i; @@ -114,6 +121,10 @@ gint cmp_background(const void *a, const void *b) if (h1->monitor == h2->monitor) return 0; + if (h1->flags & HEAD_PERAPP) --i; + if (h2->flags & HEAD_PERAPP) ++i; + if (i) return i; + if (h1->flags & HEAD_PARENT) --i; if (h2->flags & HEAD_PARENT) ++i; if (i) return i; @@ -144,7 +155,8 @@ gint cmp_background(const void *a, const void *b) } /*! Pick a monitor to place a window on. */ -static Rect *pick_head(ObClient *c, gboolean foreground) +static Rect *pick_head(ObClient *c, gboolean foreground, + ObAppSettings *settings) { Rect *area; ObPlaceHead *choice; @@ -180,6 +192,29 @@ static Rect *pick_head(ObClient *c, gboolean foreground) choice[i].flags |= HEAD_PRIMARY; if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY) choice[i].flags |= HEAD_PLACED; + if (settings && + settings->monitor_type == OB_APP_SETTINGS_MONITOR_PRIMARY) + choice[i].flags |= HEAD_PERAPP; + } + + i = screen_monitor_active(); + if (i < screen_num_monitors) { + if (settings && + settings->monitor_type == OB_APP_SETTINGS_MONITOR_ACTIVE) + choice[i].flags |= HEAD_PERAPP; + } + + i = screen_monitor_pointer(); + if (i < screen_num_monitors) { + if (settings && + settings->monitor_type == OB_APP_SETTINGS_MONITOR_MOUSE) + choice[i].flags |= HEAD_PERAPP; + } + + if (settings) { + i = settings->monitor - 1; + if (i < screen_num_monitors) + choice[i].flags |= HEAD_PERAPP; } /* direct parent takes highest precedence */ @@ -440,36 +475,15 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y) return TRUE; } -static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, +static gboolean place_per_app_setting(ObClient *client, Rect *screen, + gint *x, gint *y, ObAppSettings *settings) { - Rect *screen = NULL; - if (!settings || (settings && !settings->pos_given)) return FALSE; ob_debug("placing by per-app settings"); - /* Find which head the pointer is on */ - if (settings->monitor_type == OB_APP_SETTINGS_MONITOR_PRIMARY) { - guint m = screen_monitor_primary(TRUE); - screen = screen_area(client->desktop, m, NULL); - } - else if (settings->monitor_type == OB_APP_SETTINGS_MONITOR_ACTIVE) { - guint m = screen_monitor_active(); - screen = screen_area(client->desktop, m, NULL); - } - else if (settings->monitor_type == OB_APP_SETTINGS_MONITOR_MOUSE) { - screen = pick_pointer_head(client); - g_assert(screen); - } - else { - guint m = settings->monitor; - if (m < 1 || m > screen_num_monitors) - m = screen_monitor_primary(TRUE) + 1; - screen = screen_area(client->desktop, m - 1, NULL); - } - if (settings->position.x.center) *x = screen->x + screen->width / 2 - client->area.width / 2; else if (settings->position.x.opposite) @@ -490,7 +504,6 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y, if (settings->position.y.denom) *y = (*y * screen->height) / settings->position.y.denom; - g_slice_free(Rect, screen); return TRUE; } @@ -557,10 +570,10 @@ gboolean place_client(ObClient *client, gboolean foreground, gint *x, gint *y, !(settings && settings->pos_given))) return FALSE; - area = pick_head(client, foreground); + area = pick_head(client, foreground, settings); /* try a number of methods */ - ret = place_per_app_setting(client, x, y, settings) || + ret = place_per_app_setting(client, area, x, y, settings) || place_transient_splash(client, area, x, y) || (config_place_policy == OB_PLACE_POLICY_MOUSE && place_under_mouse(client, x, y)) || -- 2.45.2