diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2014-01-08 16:33:23 +0200 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2014-06-06 17:18:16 +0300 |
commit | 5be337ce674fe6cd955bc5c2077e86ad6c642601 (patch) | |
tree | 5299c5483ea37f0b5ffc2a095ad61811401d1ab5 /src/core | |
parent | 053602ee6c8a2ebd95e3b5b7ce529b6821d86a7f (diff) | |
download | metacity-5be337ce674fe6cd955bc5c2077e86ad6c642601.tar.gz |
add option to set window placement mode
Adapted from patch by Chad Glendenin available at:
http://chad.glendenin.com/metacity/patch.html
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/place.c | 98 | ||||
-rw-r--r-- | src/core/prefs.c | 24 |
2 files changed, 114 insertions, 8 deletions
diff --git a/src/core/place.c b/src/core/place.c index 4c20a3ff..f9dc67fc 100644 --- a/src/core/place.c +++ b/src/core/place.c @@ -639,6 +639,98 @@ find_first_fit (MetaWindow *window, return retval; } +static gboolean +find_preferred_position (MetaWindow *window, + MetaFrameGeometry *fgeom, + /* visible windows on relevant workspaces */ + GList *windows, + int xinerama, + int x, + int y, + int *new_x, + int *new_y) +{ + MetaRectangle rect; + MetaRectangle work_area; + MetaPlacementMode placement_mode_pref = meta_prefs_get_placement_mode (); + + /* If first_fit placement is the preference, just pass all the + * options through to the original find_first_fit function. + * Otherwise, process the user preference here. + */ + if (placement_mode_pref == META_PLACEMENT_MODE_SMART) + { + return find_first_fit (window, fgeom, windows, + xinerama, + x, y, new_x, new_y); + } + else if (placement_mode_pref == META_PLACEMENT_MODE_CASCADE) + { + /* This is an abuse of find_next_cascade(), because it was not + * intended for this use, and because it is not designed to + * deal with placement on multiple Xineramas. + */ + find_next_cascade (window, fgeom, windows, x, y, new_x, new_y); + return TRUE; + } + + rect.width = window->rect.width; + rect.height = window->rect.height; + + if (fgeom) + { + rect.width += fgeom->left_width + fgeom->right_width; + rect.height += fgeom->top_height + fgeom->bottom_height; + } + + meta_window_get_work_area_for_xinerama (window, xinerama, &work_area); + + /* Cannot use rect_fits_in_work_area here because that function + * also checks the x & y position of rect, but those are not set + * yet in this case. + */ + if ((rect.width <= work_area.width) && (rect.height <= work_area.height)) + { + switch (placement_mode_pref) + { + case META_PLACEMENT_MODE_CENTER: + /* This is a plain centering, different from center_tile */ + *new_x = work_area.x + ((work_area.width - rect.width) / 2); + *new_y = work_area.y + ((work_area.height - rect.height) / 2); + break; + + case META_PLACEMENT_MODE_ORIGIN: + *new_x = work_area.x; + *new_y = work_area.y; + break; + + case META_PLACEMENT_MODE_RANDOM: + *new_x = (int) ((float) (work_area.width - rect.width) * + ((float) rand() / (float) RAND_MAX)); + *new_y = (int) ((float) (work_area.height - rect.height) * + ((float) rand() / (float) RAND_MAX)); + *new_x += work_area.x; + *new_y += work_area.y; + break; + + default: + meta_warning ("Unknown window-placement option chosen.\n"); + return FALSE; + break; + } + + if (fgeom) + { + *new_x += fgeom->left_width; + *new_y += fgeom->top_height; + } + + return TRUE; + } + + return FALSE; +} + void meta_window_place (MetaWindow *window, MetaFrameGeometry *fgeom, @@ -839,9 +931,9 @@ meta_window_place (MetaWindow *window, x = xi->rect.x; y = xi->rect.y; - if (find_first_fit (window, fgeom, windows, - xi->number, - x, y, &x, &y)) + if (find_preferred_position (window, fgeom, windows, + xi->number, + x, y, &x, &y)) goto done_check_denied_focus; /* Maximize windows if they are too big for their work area (bit of diff --git a/src/core/prefs.c b/src/core/prefs.c index 7d2ce93a..3e931406 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -42,6 +42,7 @@ #define KEY_NUM_WORKSPACES "num-workspaces" #define KEY_WORKSPACE_NAMES "workspace-names" #define KEY_COMPOSITOR "compositing-manager" +#define KEY_PLACEMENT_MODE "placement-mode" /* Keys from "foreign" schemas */ #define KEY_GNOME_ACCESSIBILITY "toolkit-accessibility" @@ -92,6 +93,8 @@ static gboolean force_fullscreen = TRUE; static GDesktopVisualBellType visual_bell_type = G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH; static MetaButtonLayout button_layout; +static MetaPlacementMode placement_mode = META_PLACEMENT_MODE_SMART; + /* NULL-terminated array */ static char **workspace_names = NULL; @@ -242,6 +245,13 @@ static MetaEnumPreference preferences_enum[] = }, &action_right_click_titlebar, }, + { + { "placement-mode", + SCHEMA_METACITY, + META_PREF_PLACEMENT_MODE, + }, + &placement_mode, + }, { { NULL, 0, 0 }, NULL }, }; @@ -626,7 +636,6 @@ handle_preference_update_int (GSettings *settings, } } - /****************************************************************************/ /* Listeners. */ /****************************************************************************/ @@ -740,7 +749,6 @@ queue_changed (MetaPreference pref) changed_idle_handler, NULL, NULL); } - /****************************************************************************/ /* Initialisation. */ /****************************************************************************/ @@ -791,7 +799,6 @@ meta_prefs_init (void) init_workspace_names (); } - /****************************************************************************/ /* Updates. */ /****************************************************************************/ @@ -925,7 +932,6 @@ meta_prefs_get_cursor_size (void) return cursor_size; } - /****************************************************************************/ /* Handlers for string preferences. */ /****************************************************************************/ @@ -1412,6 +1418,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_FORCE_FULLSCREEN: return "FORCE_FULLSCREEN"; + + case META_PREF_PLACEMENT_MODE: + return "PLACEMENT_MODE"; } return "(unknown)"; @@ -1822,6 +1831,12 @@ meta_prefs_get_force_fullscreen (void) return force_fullscreen; } +MetaPlacementMode +meta_prefs_get_placement_mode (void) +{ + return placement_mode; +} + void meta_prefs_set_compositing_manager (gboolean whether) { @@ -1833,4 +1848,3 @@ meta_prefs_set_force_fullscreen (gboolean whether) { force_fullscreen = whether; } - |