diff options
author | Faidon Liambotis <[email protected]> | 2015-09-14 03:06:18 +0300 |
---|---|---|
committer | infirit <[email protected]> | 2015-09-16 13:59:59 +0200 |
commit | dee034771c8f3b519c8011faf78d277d6af76933 (patch) | |
tree | 411e2ced133401f2480a2323154b5df792b4cc31 /src/core/place.c | |
parent | e12e55167107adaa0b45decdb2f57cf7c870d2aa (diff) | |
download | marco-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.c | 52 |
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)) |