summaryrefslogtreecommitdiff
path: root/src/core/place.c
diff options
context:
space:
mode:
authorFaidon Liambotis <[email protected]>2015-09-14 03:06:18 +0300
committerinfirit <[email protected]>2015-09-16 13:59:59 +0200
commitdee034771c8f3b519c8011faf78d277d6af76933 (patch)
tree411e2ced133401f2480a2323154b5df792b4cc31 /src/core/place.c
parente12e55167107adaa0b45decdb2f57cf7c870d2aa (diff)
downloadmarco-dee034771c8f3b519c8011faf78d277d6af76933.tar.bz2
marco-dee034771c8f3b519c8011faf78d277d6af76933.tar.xz
Add manual and by-pointer window placement
This adds a window placement preference: the existing behavior is now called "automatic" and is the default. Two new modes are being introduced: "pointer", which means that windows are placed according to the mouse pointer position; and "manual" which means that the user must manually place the new window with the mouse or keyboard. This is a straight port from muffin, commit 3257671.
Diffstat (limited to 'src/core/place.c')
-rw-r--r--src/core/place.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/core/place.c b/src/core/place.c
index 99cedd14..bcfafe42 100644
--- a/src/core/place.c
+++ b/src/core/place.c
@@ -87,6 +87,47 @@ northwestcmp (gconstpointer a, gconstpointer b)
return 0;
}
+static gboolean
+place_by_pointer(MetaWindow *window,
+ MetaFrameGeometry *fgeom,
+ MetaPlacementMode placement_mode,
+ int *new_x,
+ int *new_y)
+{
+ int window_width, window_height;
+ Window root_return, child_return;
+ int root_x_return, root_y_return;
+ int win_x_return, win_y_return;
+ unsigned int mask_return;
+
+ XQueryPointer (window->display->xdisplay,
+ window->screen->xroot,
+ &root_return,
+ &child_return,
+ &root_x_return,
+ &root_y_return,
+ &win_x_return,
+ &win_y_return,
+ &mask_return);
+
+ window_width = window->frame ? window->frame->rect.width : window->rect.width;
+ window_height = window->frame ? window->frame->rect.height : window->rect.height;
+
+ if (fgeom) {
+ *new_x = root_x_return + fgeom->left_width - window_width / 2;
+ *new_y = root_y_return + fgeom->top_height - window_height / 2;
+ }
+ else {
+ *new_x = root_x_return - window_width / 2;
+ *new_y = root_y_return - window_height / 2;
+ }
+
+ if (placement_mode == META_PLACEMENT_MODE_MANUAL)
+ window->move_after_placement = TRUE;
+
+ return TRUE;
+}
+
static void
find_next_cascade (MetaWindow *window,
MetaFrameGeometry *fgeom,
@@ -663,6 +704,7 @@ meta_window_place (MetaWindow *window,
{
GList *windows;
const MetaXineramaScreenInfo *xi;
+ MetaPlacementMode placement_mode;
/* frame member variables should NEVER be used in here, only
* MetaFrameGeometry. But remember fgeom == NULL
@@ -853,6 +895,16 @@ meta_window_place (MetaWindow *window,
x = xi->rect.x;
y = xi->rect.y;
+ /* Placement based on pointer position */
+ placement_mode = meta_prefs_get_placement_mode();
+
+ if (placement_mode == META_PLACEMENT_MODE_POINTER ||
+ placement_mode == META_PLACEMENT_MODE_MANUAL)
+ {
+ if (place_by_pointer (window, fgeom, placement_mode, &x, &y))
+ goto done_check_denied_focus;
+ }
+
if (find_first_fit (window, fgeom, windows,
xi->number,
x, y, &x, &y))