summaryrefslogtreecommitdiff
path: root/src/core/place.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/place.c')
-rw-r--r--src/core/place.c214
1 files changed, 81 insertions, 133 deletions
diff --git a/src/core/place.c b/src/core/place.c
index 70171cb05..7835deeef 100644
--- a/src/core/place.c
+++ b/src/core/place.c
@@ -47,34 +47,18 @@ northwestcmp (gconstpointer a, gconstpointer b)
{
MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b;
+ MetaRectangle a_frame;
+ MetaRectangle b_frame;
int from_origin_a;
int from_origin_b;
int ax, ay, bx, by;
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- {
- ax = aw->frame->rect.x;
- ay = aw->frame->rect.y;
- }
- else
- {
- ax = aw->rect.x;
- ay = aw->rect.y;
- }
-
- if (bw->frame)
- {
- bx = bw->frame->rect.x;
- by = bw->frame->rect.y;
- }
- else
- {
- bx = bw->rect.x;
- by = bw->rect.y;
- }
+ meta_window_get_outer_rect (aw, &a_frame);
+ meta_window_get_outer_rect (bw, &b_frame);
+ ax = a_frame.x;
+ ay = a_frame.y;
+ bx = b_frame.x;
+ by = b_frame.y;
/* probably there's a fast good-enough-guess we could use here. */
from_origin_a = sqrt (ax * ax + ay * ay);
@@ -102,6 +86,7 @@ find_next_cascade (MetaWindow *window,
GList *sorted;
int cascade_x, cascade_y;
int x_threshold, y_threshold;
+ MetaRectangle frame_rect;
int window_width, window_height;
int cascade_stage;
MetaRectangle work_area;
@@ -143,30 +128,25 @@ find_next_cascade (MetaWindow *window,
cascade_y = MAX (0, work_area.y);
/* Find first cascade position that's not used. */
-
- window_width = window->frame ? window->frame->rect.width : window->rect.width;
- window_height = window->frame ? window->frame->rect.height : window->rect.height;
+
+ meta_window_get_outer_rect (window, &frame_rect);
+ window_width = frame_rect.width;
+ window_height = frame_rect.height;
cascade_stage = 0;
tmp = sorted;
while (tmp != NULL)
{
MetaWindow *w;
+ MetaRectangle w_frame_rect;
int wx, wy;
w = tmp->data;
/* we want frame position, not window position */
- if (w->frame)
- {
- wx = w->frame->rect.x;
- wy = w->frame->rect.y;
- }
- else
- {
- wx = w->rect.x;
- wy = w->rect.y;
- }
+ meta_window_get_outer_rect (w, &w_frame_rect);
+ wx = w_frame_rect.x;
+ wy = w_frame_rect.y;
if (ABS (wx - cascade_x) < x_threshold &&
ABS (wy - cascade_y) < y_threshold)
@@ -223,17 +203,8 @@ find_next_cascade (MetaWindow *window,
g_list_free (sorted);
- /* Convert coords to position of window, not position of frame. */
- if (borders == NULL)
- {
- *new_x = cascade_x;
- *new_y = cascade_y;
- }
- else
- {
- *new_x = cascade_x + borders->visible.left;
- *new_y = cascade_y + borders->visible.top;
- }
+ *new_x = cascade_x;
+ *new_y = cascade_y;
}
static void
@@ -250,14 +221,10 @@ find_most_freespace (MetaWindow *window,
int max_area;
int max_width, max_height, left, right, top, bottom;
int left_space, right_space, top_space, bottom_space;
- int frame_size_left, frame_size_top;
MetaRectangle work_area;
MetaRectangle avoid;
MetaRectangle outer;
- frame_size_left = borders ? borders->visible.left : 0;
- frame_size_top = borders ? borders->visible.top : 0;
-
meta_window_get_work_area_current_monitor (focus_window, &work_area);
meta_window_get_outer_rect (focus_window, &avoid);
meta_window_get_outer_rect (window, &outer);
@@ -304,36 +271,54 @@ find_most_freespace (MetaWindow *window,
switch (side)
{
case META_LEFT:
- *new_y = avoid.y + frame_size_top;
+ *new_y = avoid.y;
if (left_space > outer.width)
- *new_x = avoid.x - outer.width + frame_size_left;
+ *new_x = avoid.x - outer.width;
else
- *new_x = work_area.x + frame_size_left;
+ *new_x = work_area.x;
break;
case META_RIGHT:
- *new_y = avoid.y + frame_size_top;
+ *new_y = avoid.y;
if (right_space > outer.width)
- *new_x = avoid.x + avoid.width + frame_size_left;
+ *new_x = avoid.x + avoid.width;
else
- *new_x = work_area.x + work_area.width - outer.width + frame_size_left;
+ *new_x = work_area.x + work_area.width - outer.width;
break;
case META_TOP:
- *new_x = avoid.x + frame_size_left;
+ *new_x = avoid.x;
if (top_space > outer.height)
- *new_y = avoid.y - outer.height + frame_size_top;
+ *new_y = avoid.y - outer.height;
else
- *new_y = work_area.y + frame_size_top;
+ *new_y = work_area.y;
break;
case META_BOTTOM:
- *new_x = avoid.x + frame_size_left;
+ *new_x = avoid.x;
if (bottom_space > outer.height)
- *new_y = avoid.y + avoid.height + frame_size_top;
+ *new_y = avoid.y + avoid.height;
else
- *new_y = work_area.y + work_area.height - outer.height + frame_size_top;
+ *new_y = work_area.y + work_area.height - outer.height;
break;
}
}
+static gboolean
+window_overlaps_focus_window (MetaWindow *window)
+{
+ MetaWindow *focus_window;
+ MetaRectangle window_frame, focus_frame, overlap;
+
+ focus_window = window->display->focus_window;
+ if (focus_window == NULL)
+ return FALSE;
+
+ meta_window_get_outer_rect (window, &window_frame);
+ meta_window_get_outer_rect (focus_window, &focus_frame);
+
+ return meta_rectangle_intersect (&window_frame,
+ &focus_frame,
+ &overlap);
+}
+
static void
avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
MetaFrameBorders *borders,
@@ -355,16 +340,15 @@ avoid_being_obscured_as_second_modal_dialog (MetaWindow *window,
*/
MetaWindow *focus_window;
- MetaRectangle overlap;
focus_window = window->display->focus_window;
+ /* denied_focus_and_not_transient is only set when focus_window != NULL */
+
if (window->denied_focus_and_not_transient &&
window->wm_state_modal && /* FIXME: Maybe do this for all transients? */
meta_window_same_application (window, focus_window) &&
- meta_rectangle_intersect (&window->rect,
- &focus_window->rect,
- &overlap))
+ window_overlaps_focus_window (window))
{
find_most_freespace (window, borders, focus_window, *x, *y, x, y);
meta_topic (META_DEBUG_PLACEMENT,
@@ -427,20 +411,14 @@ leftmost_cmp (gconstpointer a, gconstpointer b)
{
MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b;
+ MetaRectangle a_frame;
+ MetaRectangle b_frame;
int ax, bx;
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- ax = aw->frame->rect.x;
- else
- ax = aw->rect.x;
-
- if (bw->frame)
- bx = bw->frame->rect.x;
- else
- bx = bw->rect.x;
+ meta_window_get_outer_rect (aw, &a_frame);
+ meta_window_get_outer_rect (bw, &b_frame);
+ ax = a_frame.x;
+ bx = b_frame.x;
if (ax < bx)
return -1;
@@ -455,20 +433,14 @@ topmost_cmp (gconstpointer a, gconstpointer b)
{
MetaWindow *aw = (gpointer) a;
MetaWindow *bw = (gpointer) b;
+ MetaRectangle a_frame;
+ MetaRectangle b_frame;
int ay, by;
- /* we're interested in the frame position for cascading,
- * not meta_window_get_position()
- */
- if (aw->frame)
- ay = aw->frame->rect.y;
- else
- ay = aw->rect.y;
-
- if (bw->frame)
- by = bw->frame->rect.y;
- else
- by = bw->rect.y;
+ meta_window_get_outer_rect (aw, &a_frame);
+ meta_window_get_outer_rect (bw, &b_frame);
+ ay = a_frame.y;
+ by = b_frame.y;
if (ay < by)
return -1;
@@ -540,15 +512,8 @@ find_first_fit (MetaWindow *window,
right_sorted = g_list_copy (windows);
right_sorted = g_list_sort (right_sorted, topmost_cmp);
right_sorted = g_list_sort (right_sorted, leftmost_cmp);
-
- rect.width = window->rect.width;
- rect.height = window->rect.height;
-
- if (borders)
- {
- rect.width += borders->visible.left + borders->visible.right;
- rect.height += borders->visible.top + borders->visible.bottom;
- }
+
+ meta_window_get_outer_rect (window, &rect);
#ifdef WITH_VERBOSE_MODE
{
@@ -570,11 +535,6 @@ find_first_fit (MetaWindow *window,
{
*new_x = rect.x;
*new_y = rect.y;
- if (borders)
- {
- *new_x += borders->visible.left;
- *new_y += borders->visible.top;
- }
retval = TRUE;
@@ -598,11 +558,6 @@ find_first_fit (MetaWindow *window,
{
*new_x = rect.x;
*new_y = rect.y;
- if (borders)
- {
- *new_x += borders->visible.left;
- *new_y += borders->visible.top;
- }
retval = TRUE;
@@ -629,11 +584,6 @@ find_first_fit (MetaWindow *window,
{
*new_x = rect.x;
*new_y = rect.y;
- if (borders)
- {
- *new_x += borders->visible.left;
- *new_y += borders->visible.top;
- }
retval = TRUE;
@@ -775,24 +725,22 @@ meta_window_place (MetaWindow *window,
if (parent)
{
- int w;
+ MetaRectangle frame_rect, parent_frame_rect;
- meta_window_get_position (parent, &x, &y);
- w = parent->rect.width;
+ meta_window_get_outer_rect (window, &frame_rect);
+ meta_window_get_outer_rect (parent, &parent_frame_rect);
+
+ y = parent_frame_rect.y;
/* center of parent */
- x = x + w / 2;
+ x = parent_frame_rect.x + parent_frame_rect.width / 2;
/* center of child over center of parent */
- x -= window->rect.width / 2;
+ x -= frame_rect.width / 2;
/* "visually" center window over parent, leaving twice as
* much space below as on top.
*/
- y += (parent->rect.height - window->rect.height)/3;
-
- /* put top of child's frame, not top of child's client */
- if (borders)
- y += borders->visible.top;
+ y += (parent_frame_rect.height - frame_rect.height)/3;
meta_topic (META_DEBUG_PLACEMENT, "Centered window %s over transient parent\n",
window->desc);
@@ -813,6 +761,9 @@ meta_window_place (MetaWindow *window,
{
/* Center on current monitor */
int w, h;
+ MetaRectangle frame_rect;
+
+ meta_window_get_outer_rect (window, &frame_rect);
/* Warning, this function is a round trip! */
xi = meta_screen_get_current_monitor_info (window->screen);
@@ -820,8 +771,8 @@ meta_window_place (MetaWindow *window,
w = xi->rect.width;
h = xi->rect.height;
- x = (w - window->rect.width) / 2;
- y = (h - window->rect.height) / 2;
+ x = (w - frame_rect.width) / 2;
+ y = (h - frame_rect.height) / 2;
x += xi->rect.x;
y += xi->rect.y;
@@ -909,17 +860,14 @@ meta_window_place (MetaWindow *window,
*/
if (window->denied_focus_and_not_transient)
{
- gboolean found_fit;
MetaWindow *focus_window;
- MetaRectangle overlap;
+ gboolean found_fit;
focus_window = window->display->focus_window;
g_assert (focus_window != NULL);
/* No need to do anything if the window doesn't overlap at all */
- found_fit = !meta_rectangle_intersect (&window->rect,
- &focus_window->rect,
- &overlap);
+ found_fit = !window_overlaps_focus_window (window);
/* Try to do a first fit again, this time only taking into account the
* focus window.