diff options
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | src/constraints.c | 26 | ||||
-rw-r--r-- | src/place.c | 149 | ||||
-rw-r--r-- | src/window.c | 66 | ||||
-rw-r--r-- | src/window.h | 3 |
5 files changed, 172 insertions, 107 deletions
@@ -1,5 +1,40 @@ 2003-06-09 Rob Adams <robadams@ucla.edu> + Revamp placement policy for windows that are maximized when they + are mapped, including windows that set a hint to be maximized or + windows that are auto-maximized using our heuristic. See #111902. + + * src/window.h: add new flag maximize_after_placement and new + function meta_window_maximize_internal. + + * src/window.c (meta_window_new): initialize + maximize_after_placement to FALSE and remove the automaximize + heuristic. + (meta_window_maximize_internal): new function accepts a saved_rect + argument to be used as the new saved_rect for the window, and does + not queue a move_resize. + (meta_window_maximize): re-implement using + meta_window_maximize_internal. + (update_net_wm_state): If a window has a maximize hint set on + startup set maximize_after_placement to TRUE + + * src/constraints.c (meta_window_constrain): Update the xinerama + information in the ConstraintInfo after placing the window, and + maximize the window after placement if + window->maximize_after_placement + + * src/place.c (find_first_fit): take a natural xinerama list as an + argument instead of generating it here + (constrain_placement): remove function, since it is no longer + needed + (meta_window_place): generate the natural xinerama list here and + pass it into find_first_fit. If find_first_fit fails, use the + list to find empty xineramas where we can place windows that may + be maximized later. This makes maximized windows follow the + correct placement policy. Move the automaximize heuristic here. + +2003-06-09 Rob Adams <robadams@ucla.edu> + * src/metacity-dialog.c (warn_about_no_sm_support): install an alarm to timeout the no-sm-dialog after 4 minutes of inactivity. Patch from Ximian. See #114789. diff --git a/src/constraints.c b/src/constraints.c index 7913a8c1..bc658a24 100644 --- a/src/constraints.c +++ b/src/constraints.c @@ -1119,20 +1119,38 @@ meta_window_constrain (MetaWindow *window, !window->maximized && !window->fullscreen) { - int x, y; + MetaRectangle placed_rect = current; meta_window_place (window, orig_fgeom, current.x, current.y, - &x, &y); + &placed_rect.x, &placed_rect.y); + + /* placing the window may have changed the xinerama. Find the + * new xinerama and update the ConstraintInfo + */ + info.xinerama = meta_screen_get_xinerama_for_rect (window->screen, + &placed_rect); + meta_window_get_work_area_for_xinerama (window, + info.xinerama->number, + &info.work_area_xinerama); + update_position_limits (window, &info); constrain_move (window, &info, ¤t, - x - current.x, - y - current.y, + placed_rect.x - current.x, + placed_rect.y - current.y, new); current = *new; /* Ignore any non-placement movement */ x_move_delta = 0; y_move_delta = 0; + + } + + if (window->maximize_after_placement && + window->placed) + { + window->maximize_after_placement = FALSE; + meta_window_maximize_internal (window, new); } /* Maximization, fullscreen, etc. are defined as a move followed by diff --git a/src/place.c b/src/place.c index 4e1a7dde..df480016 100644 --- a/src/place.c +++ b/src/place.c @@ -404,6 +404,8 @@ find_first_fit (MetaWindow *window, MetaFrameGeometry *fgeom, /* visible windows on relevant workspaces */ GList *windows, + int* xineramas_list, + int n_xineramas, int x, int y, int *new_x, @@ -423,8 +425,6 @@ find_first_fit (MetaWindow *window, MetaRectangle rect; MetaRectangle work_area; int i; - int* xineramas_list; - int n_xineramas; retval = FALSE; @@ -447,9 +447,6 @@ find_first_fit (MetaWindow *window, rect.height += fgeom->top_height + fgeom->bottom_height; } - meta_screen_get_natural_xinerama_list (window->screen, - &xineramas_list, - &n_xineramas); for (i = 0; i < n_xineramas; i++) { meta_topic (META_DEBUG_XINERAMA, @@ -552,68 +549,11 @@ find_first_fit (MetaWindow *window, out: - g_free (xineramas_list); g_list_free (below_sorted); g_list_free (right_sorted); return retval; } -static void -constrain_placement (MetaWindow *window, - MetaFrameGeometry *fgeom, - int x, - int y, - int *new_x, - int *new_y) -{ - /* The purpose of this function is to apply constraints that are not - * covered by window.c:constrain_position(), but should apply - * whenever we are _placing_ a window regardless of placement algorithm. - */ - MetaRectangle work_area; - int nw_x, nw_y; - int offscreen_w, offscreen_h; - MetaRectangle outer_rect; - - meta_window_get_outer_rect (window, &outer_rect); - - /* FIXME this is bogus because we get the current xinerama - * for the window based on its position, but we haven't - * placed it yet. - */ - meta_window_get_work_area_current_xinerama (window, &work_area); - - nw_x = work_area.x; - nw_y = work_area.y; - - if (window->frame) - { - nw_x += fgeom->left_width; - nw_y += fgeom->top_height; - } - - /* Keep window from going off the bottom right, though we don't have - * this constraint once the window has been placed - */ - offscreen_w = (outer_rect.x + outer_rect.width) - (work_area.x + work_area.width); - if (offscreen_w > 0) - nw_x -= offscreen_w; - offscreen_h = (outer_rect.y + outer_rect.height) - (work_area.y + work_area.height); - if (offscreen_h > 0) - nw_y -= offscreen_h; - - /* Keep window from going off left edge, though again we don't have - * this constraint once the window has been placed. - */ - if (x < nw_x) - x = nw_x; - if (y < nw_y) - y = nw_y; - - *new_x = x; - *new_y = y; -} - void meta_window_place (MetaWindow *window, MetaFrameGeometry *fgeom, @@ -624,6 +564,10 @@ meta_window_place (MetaWindow *window, { GList *windows; const MetaXineramaScreenInfo *xi; + int* xineramas_list = NULL; + int n_xineramas; + int i; + int placed_on = -1; /* frame member variables should NEVER be used in here, only * MetaFrameGeometry. But remember fgeom == NULL @@ -811,16 +755,87 @@ meta_window_place (MetaWindow *window, x = xi->x_origin; y = xi->y_origin; - if (find_first_fit (window, fgeom, windows, x, y, &x, &y)) + meta_screen_get_natural_xinerama_list (window->screen, + &xineramas_list, + &n_xineramas); + + if (find_first_fit (window, fgeom, windows, + xineramas_list, n_xineramas, + x, y, &x, &y)) goto done; - - find_next_cascade (window, fgeom, windows, x, y, &x, &y); + + /* This is a special-case origin-cascade so that windows that are + * too large to fit onto a workspace (and which will be + * automaximized later) will go onto an empty xinerama if one is + * available. + */ + if (window->has_maximize_func && window->decorated && + !window->fullscreen) + { + if (window->frame) + { + x = fgeom->left_width; + y = fgeom->top_height; + } + else + { + x = 0; + y = 0; + } + + for (i = 0; i < n_xineramas; i++) + { + MetaRectangle work_area; + + meta_window_get_work_area_for_xinerama (window, xineramas_list[i], &work_area); + + if (!rectangle_overlaps_some_window (&work_area, windows)) + { + x += work_area.x; + y += work_area.y; + placed_on = i; + break; + } + } + } + + /* if the window wasn't placed at the origin of an empty xinerama, + * cascade it onto the current xinerama + */ + if (placed_on == -1) + { + find_next_cascade (window, fgeom, windows, x, y, &x, &y); + placed_on = 0; + } + + /* Maximize windows if they are too big for their work area (bit of + * a hack here). Assume undecorated windows probably don't intend to + * be maximized. + */ + if (window->has_maximize_func && window->decorated && + !window->fullscreen) + { + MetaRectangle workarea; + MetaRectangle outer; + + meta_window_get_work_area_for_xinerama (window, + xineramas_list[placed_on], + &workarea); + meta_window_get_outer_rect (window, &outer); + + if (outer.width >= workarea.width && + outer.height >= workarea.height) + { + outer.x = x; + outer.y = y; + meta_window_maximize_internal (window, &outer); + } + } done: + g_free (xineramas_list); g_list_free (windows); - constrain_placement (window, fgeom, x, y, &x, &y); - done_no_constraints: *new_x = x; diff --git a/src/window.c b/src/window.c index ddba6a07..31af946b 100644 --- a/src/window.c +++ b/src/window.c @@ -417,6 +417,7 @@ meta_window_new (MetaDisplay *display, window->user_has_move_resized = FALSE; window->maximized = FALSE; + window->maximize_after_placement = FALSE; window->fullscreen = FALSE; window->on_all_workspaces = FALSE; window->shaded = FALSE; @@ -695,28 +696,6 @@ meta_window_new (MetaDisplay *display, } } - /* Maximize windows if they are too big for their work - * area (bit of a hack here). Assume undecorated windows - * probably don't intend to be maximized. - */ - if (window->has_maximize_func && window->decorated && - !window->fullscreen) - { - MetaRectangle workarea; - MetaRectangle outer; - - if (!window->placed) - meta_warning ("Metacity issue: using position-based current xinerama prior to placement\n"); - - meta_window_get_work_area_current_xinerama (window, &workarea); - - meta_window_get_outer_rect (window, &outer); - - if (outer.width >= workarea.width && - outer.height >= workarea.height) - meta_window_maximize (window); - } - /* Sync stack changes */ meta_stack_thaw (window->screen->stack); @@ -1841,29 +1820,44 @@ meta_window_save_rect (MetaWindow *window) } void +meta_window_maximize_internal (MetaWindow *window, + MetaRectangle *saved_rect) +{ + meta_topic (META_DEBUG_WINDOW_OPS, + "Maximizing %s\n", window->desc); + + if (saved_rect != NULL) + window->saved_rect = *saved_rect; + else + meta_window_save_rect (window); + + window->maximized = TRUE; + + recalc_window_features (window); + set_net_wm_state (window); +} + +void meta_window_maximize (MetaWindow *window) { if (!window->maximized) { - meta_topic (META_DEBUG_WINDOW_OPS, - "Maximizing %s\n", window->desc); - if (window->shaded) meta_window_unshade (window); - - meta_window_save_rect (window); - window->maximized = TRUE; + /* if the window hasn't been placed yet, we'll maximize it then + */ + if (!window->placed) + { + window->maximize_after_placement = TRUE; + return; + } + + meta_window_maximize_internal (window, NULL); - /* FIXME why did I put this here? */ - meta_window_raise (window); - /* move_resize with new maximization constraints */ meta_window_queue_move_resize (window); - - recalc_window_features (window); - set_net_wm_state (window); } } @@ -4309,9 +4303,9 @@ update_net_wm_state (MetaWindow *window) if (atoms[i] == window->display->atom_net_wm_state_shaded) window->shaded = TRUE; else if (atoms[i] == window->display->atom_net_wm_state_maximized_horz) - window->maximized = TRUE; + window->maximize_after_placement = TRUE; else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert) - window->maximized = TRUE; + window->maximize_after_placement = TRUE; else if (atoms[i] == window->display->atom_net_wm_state_modal) window->wm_state_modal = TRUE; else if (atoms[i] == window->display->atom_net_wm_state_skip_taskbar) diff --git a/src/window.h b/src/window.h index 2b6a8fa0..f9353d1e 100644 --- a/src/window.h +++ b/src/window.h @@ -94,6 +94,7 @@ struct _MetaWindow /* Whether we're maximized */ guint maximized : 1; + guint maximize_after_placement : 1; /* Whether we're shaded */ guint shaded : 1; @@ -304,6 +305,8 @@ void meta_window_queue_calc_showing (MetaWindow *window); void meta_window_minimize (MetaWindow *window); void meta_window_unminimize (MetaWindow *window); void meta_window_maximize (MetaWindow *window); +void meta_window_maximize_internal (MetaWindow *window, + MetaRectangle *saved_rect); void meta_window_unmaximize (MetaWindow *window); void meta_window_shade (MetaWindow *window); void meta_window_unshade (MetaWindow *window); |