diff options
Diffstat (limited to 'src/core/place.c')
-rw-r--r-- | src/core/place.c | 214 |
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. |