summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2014-01-08 16:33:23 +0200
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2014-06-06 17:18:16 +0300
commit5be337ce674fe6cd955bc5c2077e86ad6c642601 (patch)
tree5299c5483ea37f0b5ffc2a095ad61811401d1ab5 /src/core
parent053602ee6c8a2ebd95e3b5b7ce529b6821d86a7f (diff)
downloadmetacity-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.c98
-rw-r--r--src/core/prefs.c24
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;
}
-