Big changes to placement across multiple monitors.
Add a Primary option for which monitor to place new windows on. Make "Active" the default instead of "Any", which is just totally crazy. 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 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 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 3a. primary monitor in this set 3b. other monitors in this set 4. other monitors 4a. primary monitor in this set 4b. other monitors in this set Decide to focus the new window before placing it, so we know if it will be placed in the foreground or background. Always choose a single monitor, then place on it, rather than possibly moving to a "backup" monitor. Unpredictable monitor placement is horrible.
This commit is contained in:
parent
76ae19924d
commit
95535e8623
5 changed files with 338 additions and 280 deletions
|
@ -36,10 +36,10 @@
|
||||||
<center>yes</center>
|
<center>yes</center>
|
||||||
<!-- whether to place windows in the center of the free area found or
|
<!-- whether to place windows in the center of the free area found or
|
||||||
the top left corner -->
|
the top left corner -->
|
||||||
<monitor>Active</monitor>
|
<monitor>Primary</monitor>
|
||||||
<!-- with Smart placement on a multi-monitor system, try to place new windows
|
<!-- with Smart placement on a multi-monitor system, try to place new windows
|
||||||
on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
|
on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
|
||||||
the active window is -->
|
the active window is, 'Primary' - only on the primary monitor -->
|
||||||
<primaryMonitor>1</primaryMonitor>
|
<primaryMonitor>1</primaryMonitor>
|
||||||
<!-- The monitor where Openbox should place popup dialogs such as the
|
<!-- The monitor where Openbox should place popup dialogs such as the
|
||||||
focus cycling popup, or the desktop switch popup. It can be an index
|
focus cycling popup, or the desktop switch popup. It can be an index
|
||||||
|
|
117
openbox/client.c
117
openbox/client.c
|
@ -192,7 +192,8 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
{
|
{
|
||||||
ObClient *self;
|
ObClient *self;
|
||||||
XSetWindowAttributes attrib_set;
|
XSetWindowAttributes attrib_set;
|
||||||
gboolean activate = FALSE;
|
gboolean try_activate = FALSE;
|
||||||
|
gboolean do_activate;
|
||||||
ObAppSettings *settings;
|
ObAppSettings *settings;
|
||||||
gboolean transient = FALSE;
|
gboolean transient = FALSE;
|
||||||
Rect place;
|
Rect place;
|
||||||
|
@ -284,7 +285,7 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
FALSE, FALSE, TRUE, TRUE, FALSE, FALSE,
|
FALSE, FALSE, TRUE, TRUE, FALSE, FALSE,
|
||||||
settings->focus == 1))
|
settings->focus == 1))
|
||||||
{
|
{
|
||||||
activate = TRUE;
|
try_activate = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the client's border */
|
/* remove the client's border */
|
||||||
|
@ -298,6 +299,14 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
/* where the frame was placed is where the window was originally */
|
/* where the frame was placed is where the window was originally */
|
||||||
place = self->area;
|
place = self->area;
|
||||||
|
|
||||||
|
ob_debug("Going to try activate new window? %s",
|
||||||
|
try_activate ? "yes" : "no");
|
||||||
|
if (try_activate)
|
||||||
|
do_activate = client_can_steal_focus(self, settings->focus,
|
||||||
|
event_time(), launch_time);
|
||||||
|
else
|
||||||
|
do_activate = FALSE;
|
||||||
|
|
||||||
/* figure out placement for the window if the window is new */
|
/* figure out placement for the window if the window is new */
|
||||||
if (ob_state() == OB_STATE_RUNNING) {
|
if (ob_state() == OB_STATE_RUNNING) {
|
||||||
ob_debug("Positioned: %s @ %d %d",
|
ob_debug("Positioned: %s @ %d %d",
|
||||||
|
@ -316,7 +325,8 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
"program + user specified" :
|
"program + user specified" :
|
||||||
"BADNESS !?")))), place.width, place.height);
|
"BADNESS !?")))), place.width, place.height);
|
||||||
|
|
||||||
obplaced = place_client(self, &place.x, &place.y, settings);
|
obplaced = place_client(self, do_activate, &place.x, &place.y,
|
||||||
|
settings);
|
||||||
|
|
||||||
/* watch for buggy apps that ask to be placed at (0,0) when there is
|
/* watch for buggy apps that ask to be placed at (0,0) when there is
|
||||||
a strut there */
|
a strut there */
|
||||||
|
@ -424,13 +434,30 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
client_apply_startup_state(self, place.x, place.y,
|
client_apply_startup_state(self, place.x, place.y,
|
||||||
place.width, place.height);
|
place.width, place.height);
|
||||||
|
|
||||||
ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
|
/* grab mouse bindings before showing the window */
|
||||||
activate ? "yes" : "no");
|
mouse_grab_for_client(self, TRUE);
|
||||||
if (activate) {
|
|
||||||
activate = client_can_steal_focus(self, settings->focus,
|
|
||||||
event_time(), launch_time);
|
|
||||||
|
|
||||||
if (!activate) {
|
/* this has to happen before we try focus the window, but we want it to
|
||||||
|
happen after the client's stacking has been determined or it looks bad
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
gulong ignore_start;
|
||||||
|
if (!config_focus_under_mouse)
|
||||||
|
ignore_start = event_start_ignore_all_enters();
|
||||||
|
|
||||||
|
client_show(self);
|
||||||
|
|
||||||
|
if (!config_focus_under_mouse)
|
||||||
|
event_end_ignore_all_enters(ignore_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* activate/hilight/raise the window */
|
||||||
|
if (try_activate) {
|
||||||
|
if (do_activate) {
|
||||||
|
gboolean stacked = client_restore_session_stacking(self);
|
||||||
|
client_present(self, FALSE, !stacked, TRUE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* if the client isn't stealing focus, then hilite it so the user
|
/* if the client isn't stealing focus, then hilite it so the user
|
||||||
knows it is there, but don't do this if we're restoring from a
|
knows it is there, but don't do this if we're restoring from a
|
||||||
session */
|
session */
|
||||||
|
@ -450,27 +477,6 @@ void client_manage(Window window, ObPrompt *prompt)
|
||||||
stacking_raise(CLIENT_AS_WINDOW(self));
|
stacking_raise(CLIENT_AS_WINDOW(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse_grab_for_client(self, TRUE);
|
|
||||||
|
|
||||||
/* this has to happen before we try focus the window, but we want it to
|
|
||||||
happen after the client's stacking has been determined or it looks bad
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
gulong ignore_start;
|
|
||||||
if (!config_focus_under_mouse)
|
|
||||||
ignore_start = event_start_ignore_all_enters();
|
|
||||||
|
|
||||||
client_show(self);
|
|
||||||
|
|
||||||
if (!config_focus_under_mouse)
|
|
||||||
event_end_ignore_all_enters(ignore_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activate) {
|
|
||||||
gboolean stacked = client_restore_session_stacking(self);
|
|
||||||
client_present(self, FALSE, !stacked, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add to client list/map */
|
/* add to client list/map */
|
||||||
client_list = g_list_append(client_list, self);
|
client_list = g_list_append(client_list, self);
|
||||||
window_add(&self->window, CLIENT_AS_WINDOW(self));
|
window_add(&self->window, CLIENT_AS_WINDOW(self));
|
||||||
|
@ -693,22 +699,18 @@ static gboolean client_can_steal_focus(ObClient *self,
|
||||||
{
|
{
|
||||||
gboolean steal;
|
gboolean steal;
|
||||||
gboolean relative_focused;
|
gboolean relative_focused;
|
||||||
gboolean parent_focused;
|
|
||||||
|
|
||||||
steal = TRUE;
|
steal = TRUE;
|
||||||
|
|
||||||
parent_focused = (focus_client != NULL &&
|
|
||||||
client_search_focus_parent(self));
|
|
||||||
relative_focused = (focus_client != NULL &&
|
relative_focused = (focus_client != NULL &&
|
||||||
(client_search_focus_tree_full(self) != NULL ||
|
(client_search_focus_tree_full(self) != NULL ||
|
||||||
client_search_focus_group_full(self) != NULL));
|
client_search_focus_group_full(self) != NULL));
|
||||||
|
|
||||||
/* This is focus stealing prevention */
|
/* This is focus stealing prevention */
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Want to focus window 0x%x at time %u "
|
||||||
"Want to focus window 0x%x at time %u "
|
"launched at %u (last user interaction time %u)",
|
||||||
"launched at %u (last user interaction time %u)",
|
self->window, steal_time, launch_time,
|
||||||
self->window, steal_time, launch_time,
|
event_last_user_time);
|
||||||
event_last_user_time);
|
|
||||||
|
|
||||||
/* if it's on another desktop... */
|
/* if it's on another desktop... */
|
||||||
if (!(self->desktop == screen_desktop ||
|
if (!(self->desktop == screen_desktop ||
|
||||||
|
@ -721,15 +723,13 @@ static gboolean client_can_steal_focus(ObClient *self,
|
||||||
!event_time_after(launch_time, screen_desktop_user_time))))
|
!event_time_after(launch_time, screen_desktop_user_time))))
|
||||||
{
|
{
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because its on another desktop\n");
|
||||||
"Not focusing the window because its on another "
|
|
||||||
"desktop\n");
|
|
||||||
}
|
}
|
||||||
/* If something is focused... */
|
/* If something is focused... */
|
||||||
else if (focus_client) {
|
else if (focus_client) {
|
||||||
/* If the user is working in another window right now, then don't
|
/* If the user is working in another window right now, then don't
|
||||||
steal focus */
|
steal focus */
|
||||||
if (!parent_focused &&
|
if (!relative_focused &&
|
||||||
event_last_user_time &&
|
event_last_user_time &&
|
||||||
(!launch_time ||
|
(!launch_time ||
|
||||||
(event_time_after(event_last_user_time, launch_time) &&
|
(event_time_after(event_last_user_time, launch_time) &&
|
||||||
|
@ -738,18 +738,15 @@ static gboolean client_can_steal_focus(ObClient *self,
|
||||||
steal_time - OB_EVENT_USER_TIME_DELAY))
|
steal_time - OB_EVENT_USER_TIME_DELAY))
|
||||||
{
|
{
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because the user is "
|
||||||
"Not focusing the window because the user is "
|
"working in another window that is not its relative");
|
||||||
"working in another window that is not "
|
|
||||||
"its parent");
|
|
||||||
}
|
}
|
||||||
/* If the new window is a transient (and its relatives aren't
|
/* If the new window is a transient (and its relatives aren't
|
||||||
focused) */
|
focused) */
|
||||||
else if (client_has_parent(self) && !relative_focused) {
|
else if (client_has_parent(self) && !relative_focused) {
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because it is a "
|
||||||
"Not focusing the window because it is a "
|
"transient, and its relatives aren't focused");
|
||||||
"transient, and its relatives aren't focused");
|
|
||||||
}
|
}
|
||||||
/* Don't steal focus from globally active clients.
|
/* Don't steal focus from globally active clients.
|
||||||
I stole this idea from KWin. It seems nice.
|
I stole this idea from KWin. It seems nice.
|
||||||
|
@ -758,17 +755,15 @@ static gboolean client_can_steal_focus(ObClient *self,
|
||||||
focus_client->focus_notify))
|
focus_client->focus_notify))
|
||||||
{
|
{
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because a globally "
|
||||||
"Not focusing the window because a globally "
|
"active client has focus");
|
||||||
"active client has focus");
|
|
||||||
}
|
}
|
||||||
/* Don't move focus if it's not going to go to this window
|
/* Don't move focus if it's not going to go to this window
|
||||||
anyway */
|
anyway */
|
||||||
else if (client_focus_target(self) != self) {
|
else if (client_focus_target(self) != self) {
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because another window "
|
||||||
"Not focusing the window because another window "
|
"would get the focus anyway");
|
||||||
"would get the focus anyway");
|
|
||||||
}
|
}
|
||||||
/* Don't move focus if the window is not visible on the current
|
/* Don't move focus if the window is not visible on the current
|
||||||
desktop and none of its relatives are focused */
|
desktop and none of its relatives are focused */
|
||||||
|
@ -777,17 +772,15 @@ static gboolean client_can_steal_focus(ObClient *self,
|
||||||
!relative_focused)
|
!relative_focused)
|
||||||
{
|
{
|
||||||
steal = FALSE;
|
steal = FALSE;
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Not focusing the window because it is on "
|
||||||
"Not focusing the window because it is on "
|
"another desktop and no relatives are focused ");
|
||||||
"another desktop and no relatives are focused ");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!steal)
|
if (!steal)
|
||||||
ob_debug_type(OB_DEBUG_FOCUS,
|
ob_debug("Focus stealing prevention activated for %s at "
|
||||||
"Focus stealing prevention activated for %s at "
|
"time %u (last user interaction time %u)",
|
||||||
"time %u (last user interaction time %u)",
|
self->title, steal_time, event_last_user_time);
|
||||||
self->title, steal_time, event_last_user_time);
|
|
||||||
return steal;
|
return steal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -582,6 +582,8 @@ static void parse_placement(xmlNodePtr node, gpointer d)
|
||||||
config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
|
config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
|
||||||
else if (obt_xml_node_contains(n, "mouse"))
|
else if (obt_xml_node_contains(n, "mouse"))
|
||||||
config_place_monitor = OB_PLACE_MONITOR_MOUSE;
|
config_place_monitor = OB_PLACE_MONITOR_MOUSE;
|
||||||
|
else if (obt_xml_node_contains(n, "any"))
|
||||||
|
config_place_monitor = OB_PLACE_MONITOR_ANY;
|
||||||
}
|
}
|
||||||
if ((n = obt_xml_find_node(node, "primaryMonitor"))) {
|
if ((n = obt_xml_find_node(node, "primaryMonitor"))) {
|
||||||
config_primary_monitor_index = obt_xml_node_int(n);
|
config_primary_monitor_index = obt_xml_node_int(n);
|
||||||
|
@ -1003,7 +1005,7 @@ void config_startup(ObtXmlInst *i)
|
||||||
|
|
||||||
config_place_policy = OB_PLACE_POLICY_SMART;
|
config_place_policy = OB_PLACE_POLICY_SMART;
|
||||||
config_place_center = TRUE;
|
config_place_center = TRUE;
|
||||||
config_place_monitor = OB_PLACE_MONITOR_ANY;
|
config_place_monitor = OB_PLACE_MONITOR_PRIMARY;
|
||||||
|
|
||||||
config_primary_monitor_index = 1;
|
config_primary_monitor_index = 1;
|
||||||
config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
|
config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
|
||||||
|
|
486
openbox/place.c
486
openbox/place.c
|
@ -28,129 +28,207 @@
|
||||||
|
|
||||||
extern ObDock *dock;
|
extern ObDock *dock;
|
||||||
|
|
||||||
static void add_choice(guint *choice, guint mychoice)
|
|
||||||
{
|
|
||||||
guint i;
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i) {
|
|
||||||
if (choice[i] == mychoice)
|
|
||||||
return;
|
|
||||||
else if (choice[i] == screen_num_monitors) {
|
|
||||||
choice[i] = mychoice;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Rect *pick_pointer_head(ObClient *c)
|
static Rect *pick_pointer_head(ObClient *c)
|
||||||
{
|
{
|
||||||
return screen_area(c->desktop, screen_monitor_pointer(), NULL);
|
return screen_area(c->desktop, screen_monitor_pointer(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Pick a monitor to place a window on. */
|
/* use the following priority lists for pick_head()
|
||||||
static Rect **pick_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
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
3a. primary monitor in this set
|
||||||
|
3b. other monitors in this set
|
||||||
|
4. other monitors
|
||||||
|
4a. primary monitor in this set
|
||||||
|
4b. other monitors in this set
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! One for each possible head, used to sort them in order of precedence. */
|
||||||
|
typedef struct {
|
||||||
|
guint monitor;
|
||||||
|
guint flags;
|
||||||
|
} ObPlaceHead;
|
||||||
|
|
||||||
|
/*! Flags for ObPlaceHead */
|
||||||
|
enum {
|
||||||
|
HEAD_PARENT = 1 << 0, /* parent's monitor */
|
||||||
|
HEAD_PLACED = 1 << 1, /* chosen monitor by placement */
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
gint cmp_foreground(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
Rect **area;
|
const ObPlaceHead *h1 = a;
|
||||||
guint *choice;
|
const ObPlaceHead *h2 = b;
|
||||||
|
gint i = 0;
|
||||||
|
|
||||||
|
if (h1->monitor == h2->monitor) return 0;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_PARENT) --i;
|
||||||
|
if (h2->flags & HEAD_PARENT) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_PLACED) --i;
|
||||||
|
if (h2->flags & HEAD_PLACED) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_PRIMARY) --i;
|
||||||
|
if (h2->flags & HEAD_PRIMARY) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_GROUP_DESK) --i;
|
||||||
|
if (h2->flags & HEAD_GROUP_DESK) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_GROUP) --i;
|
||||||
|
if (h2->flags & HEAD_GROUP) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
return h1->monitor - h2->monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
gint cmp_background(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const ObPlaceHead *h1 = a;
|
||||||
|
const ObPlaceHead *h2 = b;
|
||||||
|
gint i = 0;
|
||||||
|
|
||||||
|
if (h1->monitor == h2->monitor) return 0;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_PARENT) --i;
|
||||||
|
if (h2->flags & HEAD_PARENT) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_GROUP_DESK || h2->flags & HEAD_GROUP_DESK) {
|
||||||
|
if (h1->flags & HEAD_GROUP_DESK) --i;
|
||||||
|
if (h2->flags & HEAD_GROUP_DESK) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
if (h1->flags & HEAD_PRIMARY) --i;
|
||||||
|
if (h2->flags & HEAD_PRIMARY) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_GROUP || h2->flags & HEAD_GROUP) {
|
||||||
|
if (h1->flags & HEAD_GROUP) --i;
|
||||||
|
if (h2->flags & HEAD_GROUP) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
if (h1->flags & HEAD_PRIMARY) --i;
|
||||||
|
if (h2->flags & HEAD_PRIMARY) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h1->flags & HEAD_PRIMARY) --i;
|
||||||
|
if (h2->flags & HEAD_PRIMARY) ++i;
|
||||||
|
if (i) return i;
|
||||||
|
|
||||||
|
return h1->monitor - h2->monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Pick a monitor to place a window on. */
|
||||||
|
static Rect *pick_head(ObClient *c, gboolean foreground)
|
||||||
|
{
|
||||||
|
Rect *area;
|
||||||
|
ObPlaceHead *choice;
|
||||||
guint i;
|
guint i;
|
||||||
gint px, py;
|
|
||||||
ObClient *p;
|
ObClient *p;
|
||||||
|
GSList *it;
|
||||||
|
|
||||||
area = g_new(Rect*, screen_num_monitors);
|
choice = g_new(ObPlaceHead, screen_num_monitors);
|
||||||
choice = g_new(guint, screen_num_monitors);
|
for (i = 0; i < screen_num_monitors; ++i) {
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
choice[i].monitor = i;
|
||||||
choice[i] = screen_num_monitors; /* make them all invalid to start */
|
choice[i].flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* try direct parent first */
|
/* find monitors with group members */
|
||||||
|
for (it = c->group->members; it; it = g_slist_next(it)) {
|
||||||
|
ObClient *itc = it->data;
|
||||||
|
if (itc != c) {
|
||||||
|
guint m = client_monitor(itc);
|
||||||
|
|
||||||
|
if (m < screen_num_monitors) {
|
||||||
|
if (screen_compare_desktops(itc->desktop, c->desktop))
|
||||||
|
choice[m].flags |= HEAD_GROUP_DESK;
|
||||||
|
else
|
||||||
|
choice[m].flags |= HEAD_GROUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i = screen_monitor_primary(FALSE);
|
||||||
|
if (i < screen_num_monitors) {
|
||||||
|
choice[i].flags |= HEAD_PRIMARY;
|
||||||
|
if (config_place_monitor == OB_PLACE_MONITOR_PRIMARY)
|
||||||
|
choice[i].flags |= HEAD_PLACED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* direct parent takes highest precedence */
|
||||||
if ((p = client_direct_parent(c))) {
|
if ((p = client_direct_parent(c))) {
|
||||||
add_choice(choice, client_monitor(p));
|
i = client_monitor(p);
|
||||||
ob_debug("placement adding choice %d for parent",
|
if (i < screen_num_monitors)
|
||||||
client_monitor(p));
|
choice[i].flags |= HEAD_PARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* more than one window in its group (more than just this window) */
|
qsort(choice, screen_num_monitors, sizeof(ObPlaceHead),
|
||||||
if (client_has_group_siblings(c)) {
|
foreground ? cmp_foreground : cmp_background);
|
||||||
GSList *it;
|
|
||||||
|
|
||||||
/* try on the client's desktop */
|
/* save the areas of the monitors in order of their being chosen */
|
||||||
for (it = c->group->members; it; it = g_slist_next(it)) {
|
for (i = 0; i < screen_num_monitors; ++i)
|
||||||
ObClient *itc = it->data;
|
|
||||||
if (itc != c &&
|
|
||||||
(itc->desktop == c->desktop ||
|
|
||||||
itc->desktop == DESKTOP_ALL || c->desktop == DESKTOP_ALL))
|
|
||||||
{
|
|
||||||
add_choice(choice, client_monitor(it->data));
|
|
||||||
ob_debug("placement adding choice %d for group sibling",
|
|
||||||
client_monitor(it->data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* try on all desktops */
|
|
||||||
for (it = c->group->members; it; it = g_slist_next(it)) {
|
|
||||||
ObClient *itc = it->data;
|
|
||||||
if (itc != c) {
|
|
||||||
add_choice(choice, client_monitor(it->data));
|
|
||||||
ob_debug("placement adding choice %d for group sibling on "
|
|
||||||
"another desktop", client_monitor(it->data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip this if placing by the mouse position */
|
|
||||||
if (focus_client && client_normal(focus_client) &&
|
|
||||||
config_place_monitor != OB_PLACE_MONITOR_MOUSE)
|
|
||||||
{
|
{
|
||||||
add_choice(choice, client_monitor(focus_client));
|
ob_debug("placement choice %d is monitor %d", i, choice[i].monitor);
|
||||||
ob_debug("placement adding choice %d for normal focused window",
|
if (choice[i].flags & HEAD_PARENT)
|
||||||
client_monitor(focus_client));
|
ob_debug(" - parent on monitor");
|
||||||
|
if (choice[i].flags & HEAD_PLACED)
|
||||||
|
ob_debug(" - placement choice");
|
||||||
|
if (choice[i].flags & HEAD_PRIMARY)
|
||||||
|
ob_debug(" - primary monitor");
|
||||||
|
if (choice[i].flags & HEAD_GROUP_DESK)
|
||||||
|
ob_debug(" - group on same desktop");
|
||||||
|
if (choice[i].flags & HEAD_GROUP)
|
||||||
|
ob_debug(" - group on other desktop");
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_pointer_pos(&px, &py);
|
area = screen_area(c->desktop, choice[0].monitor, NULL);
|
||||||
|
|
||||||
for (i = 0; i < screen_num_monitors; i++) {
|
|
||||||
const Rect *monitor = screen_physical_area_monitor(i);
|
|
||||||
gboolean contain = RECT_CONTAINS(*monitor, px, py);
|
|
||||||
if (contain) {
|
|
||||||
add_choice(choice, i);
|
|
||||||
ob_debug("placement adding choice %d for mouse pointer", i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add any leftover choices */
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
|
||||||
add_choice(choice, i);
|
|
||||||
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
|
||||||
area[i] = screen_area(c->desktop, choice[i], NULL);
|
|
||||||
|
|
||||||
g_free(choice);
|
g_free(choice);
|
||||||
|
|
||||||
|
/* return the area for the chosen monitor */
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean place_random(ObClient *client, gint *x, gint *y)
|
static gboolean place_random(ObClient *client, Rect *area, gint *x, gint *y)
|
||||||
{
|
{
|
||||||
gint l, r, t, b;
|
gint l, r, t, b;
|
||||||
Rect **areas;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
areas = pick_head(client);
|
ob_debug("placing randomly");
|
||||||
i = (config_place_monitor != OB_PLACE_MONITOR_ANY) ?
|
|
||||||
0 : g_random_int_range(0, screen_num_monitors);
|
|
||||||
|
|
||||||
l = areas[i]->x;
|
l = area->x;
|
||||||
t = areas[i]->y;
|
t = area->y;
|
||||||
r = areas[i]->x + areas[i]->width - client->frame->area.width;
|
r = area->x + area->width - client->frame->area.width;
|
||||||
b = areas[i]->y + areas[i]->height - client->frame->area.height;
|
b = area->y + area->height - client->frame->area.height;
|
||||||
|
|
||||||
if (r > l) *x = g_random_int_range(l, r + 1);
|
if (r > l) *x = g_random_int_range(l, r + 1);
|
||||||
else *x = areas[i]->x;
|
else *x = area->x;
|
||||||
if (b > t) *y = g_random_int_range(t, b + 1);
|
if (b > t) *y = g_random_int_range(t, b + 1);
|
||||||
else *y = areas[i]->y;
|
else *y = area->y;
|
||||||
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
|
||||||
g_slice_free(Rect, areas[i]);
|
|
||||||
g_free(areas);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -228,118 +306,108 @@ enum {
|
||||||
IGNORE_END = 7
|
IGNORE_END = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
static gboolean place_nooverlap(ObClient *c, gint *x, gint *y)
|
static gboolean place_nooverlap(ObClient *c, Rect *area, gint *x, gint *y)
|
||||||
{
|
{
|
||||||
Rect **areas;
|
|
||||||
gint ignore;
|
gint ignore;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
gint maxsize;
|
gint maxsize;
|
||||||
GSList *spaces = NULL, *sit, *maxit;
|
GSList *spaces = NULL, *sit, *maxit;
|
||||||
guint i;
|
|
||||||
|
|
||||||
areas = pick_head(c);
|
ob_debug("placing nonoverlap");
|
||||||
|
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
maxsize = 0;
|
maxsize = 0;
|
||||||
maxit = NULL;
|
maxit = NULL;
|
||||||
|
|
||||||
/* try ignoring different things to find empty space */
|
/* try ignoring different things to find empty space */
|
||||||
for (ignore = 0; ignore < IGNORE_END && !ret; ignore++) {
|
for (ignore = 0; ignore < IGNORE_END && !ret; ignore++) {
|
||||||
/* try all monitors in order of preference, but only the first one
|
GList *it;
|
||||||
if config_place_monitor is MOUSE or ACTIVE */
|
|
||||||
for (i = 0; (i < (config_place_monitor != OB_PLACE_MONITOR_ANY ?
|
|
||||||
1 : screen_num_monitors) && !ret); ++i)
|
|
||||||
{
|
|
||||||
GList *it;
|
|
||||||
|
|
||||||
/* add the whole monitor */
|
/* add the whole monitor */
|
||||||
spaces = area_add(spaces, areas[i]);
|
spaces = area_add(spaces, area);
|
||||||
|
|
||||||
/* go thru all the windows */
|
/* go thru all the windows */
|
||||||
for (it = client_list; it; it = g_list_next(it)) {
|
for (it = client_list; it; it = g_list_next(it)) {
|
||||||
ObClient *test = it->data;
|
ObClient *test = it->data;
|
||||||
|
|
||||||
/* should we ignore this client? */
|
/* should we ignore this client? */
|
||||||
if (screen_showing_desktop) continue;
|
if (screen_showing_desktop) continue;
|
||||||
if (c == test) continue;
|
if (c == test) continue;
|
||||||
if (test->iconic) continue;
|
if (test->iconic) continue;
|
||||||
if (c->desktop != DESKTOP_ALL) {
|
if (c->desktop != DESKTOP_ALL) {
|
||||||
if (test->desktop != c->desktop &&
|
if (test->desktop != c->desktop &&
|
||||||
test->desktop != DESKTOP_ALL) continue;
|
test->desktop != DESKTOP_ALL) continue;
|
||||||
} else {
|
} else {
|
||||||
if (test->desktop != screen_desktop &&
|
if (test->desktop != screen_desktop &&
|
||||||
test->desktop != DESKTOP_ALL) continue;
|
test->desktop != DESKTOP_ALL) continue;
|
||||||
}
|
|
||||||
if (test->type == OB_CLIENT_TYPE_SPLASH ||
|
|
||||||
test->type == OB_CLIENT_TYPE_DESKTOP) continue;
|
|
||||||
|
|
||||||
|
|
||||||
if ((ignore >= IGNORE_FULLSCREEN) &&
|
|
||||||
test->fullscreen) continue;
|
|
||||||
if ((ignore >= IGNORE_MAXIMIZED) &&
|
|
||||||
test->max_horz && test->max_vert) continue;
|
|
||||||
if ((ignore >= IGNORE_MENUTOOL) &&
|
|
||||||
(test->type == OB_CLIENT_TYPE_MENU ||
|
|
||||||
test->type == OB_CLIENT_TYPE_TOOLBAR) &&
|
|
||||||
client_has_parent(c)) continue;
|
|
||||||
/*
|
|
||||||
if ((ignore >= IGNORE_SHADED) &&
|
|
||||||
test->shaded) continue;
|
|
||||||
*/
|
|
||||||
if ((ignore >= IGNORE_NONGROUP) &&
|
|
||||||
client_has_group_siblings(c) &&
|
|
||||||
test->group != c->group) continue;
|
|
||||||
if ((ignore >= IGNORE_BELOW) &&
|
|
||||||
test->layer < c->layer) continue;
|
|
||||||
/*
|
|
||||||
if ((ignore >= IGNORE_NONFOCUS) &&
|
|
||||||
focus_client != test) continue;
|
|
||||||
*/
|
|
||||||
/* don't ignore this window, so remove it from the available
|
|
||||||
area */
|
|
||||||
spaces = area_remove(spaces, &test->frame->area);
|
|
||||||
}
|
}
|
||||||
|
if (test->type == OB_CLIENT_TYPE_SPLASH ||
|
||||||
|
test->type == OB_CLIENT_TYPE_DESKTOP) continue;
|
||||||
|
|
||||||
if (ignore < IGNORE_DOCK) {
|
|
||||||
Rect a;
|
if ((ignore >= IGNORE_FULLSCREEN) &&
|
||||||
dock_get_area(&a);
|
test->fullscreen) continue;
|
||||||
spaces = area_remove(spaces, &a);
|
if ((ignore >= IGNORE_MAXIMIZED) &&
|
||||||
|
test->max_horz && test->max_vert) continue;
|
||||||
|
if ((ignore >= IGNORE_MENUTOOL) &&
|
||||||
|
(test->type == OB_CLIENT_TYPE_MENU ||
|
||||||
|
test->type == OB_CLIENT_TYPE_TOOLBAR) &&
|
||||||
|
client_has_parent(c)) continue;
|
||||||
|
/*
|
||||||
|
if ((ignore >= IGNORE_SHADED) &&
|
||||||
|
test->shaded) continue;
|
||||||
|
*/
|
||||||
|
if ((ignore >= IGNORE_NONGROUP) &&
|
||||||
|
client_has_group_siblings(c) &&
|
||||||
|
test->group != c->group) continue;
|
||||||
|
if ((ignore >= IGNORE_BELOW) &&
|
||||||
|
test->layer < c->layer) continue;
|
||||||
|
/*
|
||||||
|
if ((ignore >= IGNORE_NONFOCUS) &&
|
||||||
|
focus_client != test) continue;
|
||||||
|
*/
|
||||||
|
/* don't ignore this window, so remove it from the available
|
||||||
|
area */
|
||||||
|
spaces = area_remove(spaces, &test->frame->area);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignore < IGNORE_DOCK) {
|
||||||
|
Rect a;
|
||||||
|
dock_get_area(&a);
|
||||||
|
spaces = area_remove(spaces, &a);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (sit = spaces; sit; sit = g_slist_next(sit)) {
|
||||||
|
Rect *r = sit->data;
|
||||||
|
|
||||||
|
if (r->width >= c->frame->area.width &&
|
||||||
|
r->height >= c->frame->area.height &&
|
||||||
|
r->width * r->height > maxsize)
|
||||||
|
{
|
||||||
|
maxsize = r->width * r->height;
|
||||||
|
maxit = sit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (sit = spaces; sit; sit = g_slist_next(sit)) {
|
if (maxit) {
|
||||||
Rect *r = sit->data;
|
Rect *r = maxit->data;
|
||||||
|
|
||||||
if (r->width >= c->frame->area.width &&
|
/* center it in the area */
|
||||||
r->height >= c->frame->area.height &&
|
*x = r->x;
|
||||||
r->width * r->height > maxsize)
|
*y = r->y;
|
||||||
{
|
if (config_place_center) {
|
||||||
maxsize = r->width * r->height;
|
*x += (r->width - c->frame->area.width) / 2;
|
||||||
maxit = sit;
|
*y += (r->height - c->frame->area.height) / 2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxit) {
|
while (spaces) {
|
||||||
Rect *r = maxit->data;
|
g_slice_free(Rect, spaces->data);
|
||||||
|
spaces = g_slist_delete_link(spaces, spaces);
|
||||||
/* center it in the area */
|
|
||||||
*x = r->x;
|
|
||||||
*y = r->y;
|
|
||||||
if (config_place_center) {
|
|
||||||
*x += (r->width - c->frame->area.width) / 2;
|
|
||||||
*y += (r->height - c->frame->area.height) / 2;
|
|
||||||
}
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (spaces) {
|
|
||||||
g_slice_free(Rect, spaces->data);
|
|
||||||
spaces = g_slist_delete_link(spaces, spaces);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
|
||||||
g_slice_free(Rect, areas[i]);
|
|
||||||
g_free(areas);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +417,8 @@ static gboolean place_under_mouse(ObClient *client, gint *x, gint *y)
|
||||||
gint px, py;
|
gint px, py;
|
||||||
Rect *area;
|
Rect *area;
|
||||||
|
|
||||||
|
ob_debug("placing under mouse");
|
||||||
|
|
||||||
if (!screen_pointer_pos(&px, &py))
|
if (!screen_pointer_pos(&px, &py))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
area = pick_pointer_head(client);
|
area = pick_pointer_head(client);
|
||||||
|
@ -376,27 +446,17 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
|
||||||
if (!settings || (settings && !settings->pos_given))
|
if (!settings || (settings && !settings->pos_given))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
ob_debug("placing by per-app settings");
|
||||||
|
|
||||||
/* Find which head the pointer is on */
|
/* Find which head the pointer is on */
|
||||||
if (settings->monitor == 0)
|
if (settings->monitor == 0)
|
||||||
/* this can return NULL */
|
/* this can return NULL */
|
||||||
screen = pick_pointer_head(client);
|
screen = pick_pointer_head(client);
|
||||||
else if (settings->monitor > 0 &&
|
else {
|
||||||
(guint)settings->monitor <= screen_num_monitors)
|
guint m = settings->monitor;
|
||||||
screen = screen_area(client->desktop, (guint)settings->monitor - 1,
|
if (m < 1 || m > screen_num_monitors)
|
||||||
NULL);
|
m = screen_monitor_primary(TRUE) + 1;
|
||||||
|
screen = screen_area(client->desktop, m - 1, NULL);
|
||||||
/* if we have't found a screen yet.. */
|
|
||||||
if (!screen) {
|
|
||||||
Rect **areas;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
areas = pick_head(client);
|
|
||||||
screen = areas[0];
|
|
||||||
|
|
||||||
/* don't free the first one, it's being set as "screen" */
|
|
||||||
for (i = 1; i < screen_num_monitors; ++i)
|
|
||||||
g_slice_free(Rect, areas[i]);
|
|
||||||
g_free(areas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->position.x.center)
|
if (settings->position.x.center)
|
||||||
|
@ -423,12 +483,16 @@ static gboolean place_per_app_setting(ObClient *client, gint *x, gint *y,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
|
static gboolean place_transient_splash(ObClient *client, Rect *area,
|
||||||
|
gint *x, gint *y)
|
||||||
{
|
{
|
||||||
if (client->type == OB_CLIENT_TYPE_DIALOG) {
|
if (client->type == OB_CLIENT_TYPE_DIALOG) {
|
||||||
GSList *it;
|
GSList *it;
|
||||||
gboolean first = TRUE;
|
gboolean first = TRUE;
|
||||||
gint l, r, t, b;
|
gint l, r, t, b;
|
||||||
|
|
||||||
|
ob_debug("placing dialog");
|
||||||
|
|
||||||
for (it = client->parents; it; it = g_slist_next(it)) {
|
for (it = client->parents; it; it = g_slist_next(it)) {
|
||||||
ObClient *m = it->data;
|
ObClient *m = it->data;
|
||||||
if (!m->iconic) {
|
if (!m->iconic) {
|
||||||
|
@ -456,17 +520,10 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
|
||||||
if (client->type == OB_CLIENT_TYPE_DIALOG ||
|
if (client->type == OB_CLIENT_TYPE_DIALOG ||
|
||||||
client->type == OB_CLIENT_TYPE_SPLASH)
|
client->type == OB_CLIENT_TYPE_SPLASH)
|
||||||
{
|
{
|
||||||
Rect **areas;
|
ob_debug("placing dialog or splash");
|
||||||
guint i;
|
|
||||||
|
|
||||||
areas = pick_head(client);
|
*x = (area->width - client->frame->area.width) / 2 + area->x;
|
||||||
|
*y = (area->height - client->frame->area.height) / 2 + area->y;
|
||||||
*x = (areas[0]->width - client->frame->area.width) / 2 + areas[0]->x;
|
|
||||||
*y = (areas[0]->height - client->frame->area.height) / 2 + areas[0]->y;
|
|
||||||
|
|
||||||
for (i = 0; i < screen_num_monitors; ++i)
|
|
||||||
g_slice_free(Rect, areas[i]);
|
|
||||||
g_free(areas);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,9 +532,10 @@ static gboolean place_transient_splash(ObClient *client, gint *x, gint *y)
|
||||||
|
|
||||||
/*! Return TRUE if openbox chose the position for the window, and FALSE if
|
/*! Return TRUE if openbox chose the position for the window, and FALSE if
|
||||||
the application chose it */
|
the application chose it */
|
||||||
gboolean place_client(ObClient *client, gint *x, gint *y,
|
gboolean place_client(ObClient *client, gboolean foreground, gint *x, gint *y,
|
||||||
ObAppSettings *settings)
|
ObAppSettings *settings)
|
||||||
{
|
{
|
||||||
|
Rect *area;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
/* per-app settings override program specified position
|
/* per-app settings override program specified position
|
||||||
|
@ -488,15 +546,19 @@ gboolean place_client(ObClient *client, gint *x, gint *y,
|
||||||
!(settings && settings->pos_given)))
|
!(settings && settings->pos_given)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
area = pick_head(client, foreground);
|
||||||
|
|
||||||
/* try a number of methods */
|
/* try a number of methods */
|
||||||
ret = place_per_app_setting(client, x, y, settings) ||
|
ret = place_per_app_setting(client, x, y, settings) ||
|
||||||
place_transient_splash(client, x, y) ||
|
place_transient_splash(client, area, x, y) ||
|
||||||
(config_place_policy == OB_PLACE_POLICY_MOUSE &&
|
(config_place_policy == OB_PLACE_POLICY_MOUSE &&
|
||||||
place_under_mouse(client, x, y)) ||
|
place_under_mouse(client, x, y)) ||
|
||||||
place_nooverlap(client, x, y) ||
|
place_nooverlap(client, area, x, y) ||
|
||||||
place_random(client, x, y);
|
place_random(client, area, x, y);
|
||||||
g_assert(ret);
|
g_assert(ret);
|
||||||
|
|
||||||
|
g_slice_free(Rect, area);
|
||||||
|
|
||||||
/* get where the client should be */
|
/* get where the client should be */
|
||||||
frame_frame_gravity(client->frame, x, y);
|
frame_frame_gravity(client->frame, x, y);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -35,10 +35,11 @@ typedef enum
|
||||||
{
|
{
|
||||||
OB_PLACE_MONITOR_ANY,
|
OB_PLACE_MONITOR_ANY,
|
||||||
OB_PLACE_MONITOR_ACTIVE,
|
OB_PLACE_MONITOR_ACTIVE,
|
||||||
OB_PLACE_MONITOR_MOUSE
|
OB_PLACE_MONITOR_MOUSE,
|
||||||
|
OB_PLACE_MONITOR_PRIMARY
|
||||||
} ObPlaceMonitor;
|
} ObPlaceMonitor;
|
||||||
|
|
||||||
gboolean place_client(struct _ObClient *client, gint *x, gint *y,
|
gboolean place_client(struct _ObClient *client, gboolean foreground,
|
||||||
struct _ObAppSettings *settings);
|
gint *x, gint *y, struct _ObAppSettings *settings);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue