summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/place.c52
-rw-r--r--src/core/prefs.c16
-rw-r--r--src/core/window-private.h3
-rw-r--r--src/core/window.c8
-rw-r--r--src/include/common.h10
-rw-r--r--src/include/prefs.h5
-rw-r--r--src/org.mate.marco.gschema.xml10
7 files changed, 103 insertions, 1 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))
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 8fa28b83..2f3e9392 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -168,6 +168,8 @@ static void init_window_bindings (void);
static void init_commands (void);
static void init_workspace_names (void);
+static MetaPlacementMode placement_mode = META_PLACEMENT_MODE_AUTOMATIC;
+
typedef struct
{
MetaPrefsChangedFunc func;
@@ -317,6 +319,11 @@ static MetaEnumPreference preferences_enum[] =
META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
(gint *) &action_right_click_titlebar,
},
+ { "placement-mode",
+ KEY_GENERAL_SCHEMA,
+ META_PREF_PLACEMENT_MODE,
+ (gint *) &placement_mode,
+ },
{ NULL, NULL, 0, NULL },
};
@@ -1556,6 +1563,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_SIDE_BY_SIDE_TILING:
return "SIDE_BY_SIDE_TILING";
+
+ case META_PREF_PLACEMENT_MODE:
+ return "PLACEMENT_MODE";
}
return "(unknown)";
@@ -2241,6 +2251,12 @@ meta_prefs_get_force_fullscreen (void)
return force_fullscreen;
}
+MetaPlacementMode
+meta_prefs_get_placement_mode (void)
+{
+ return placement_mode;
+}
+
void
meta_prefs_set_force_compositing_manager (gboolean whether)
{
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 20e619cb..0b3cf594 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -139,6 +139,9 @@ struct _MetaWindow
guint maximize_vertically_after_placement : 1;
guint minimize_after_placement : 1;
+ /* Whether to move after placement */
+ guint move_after_placement : 1;
+
/* The current or requested tile mode. If maximized_vertically is true,
* this is the current mode. If not, it is the mode which will be
* requested after the window grab is released */
diff --git a/src/core/window.c b/src/core/window.c
index 60616e4d..30ebfa85 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -461,6 +461,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
window->minimize_after_placement = FALSE;
+ window->move_after_placement = FALSE;
window->fullscreen = FALSE;
window->fullscreen_after_placement = FALSE;
window->fullscreen_monitors[0] = -1;
@@ -2346,6 +2347,13 @@ meta_window_show (MetaWindow *window)
if (takes_focus_on_map)
{
meta_window_focus (window, timestamp);
+
+ if (window->move_after_placement)
+ {
+ meta_window_begin_grab_op(window, META_GRAB_OP_KEYBOARD_MOVING,
+ FALSE, timestamp);
+ window->move_after_placement = FALSE;
+ }
}
else
{
diff --git a/src/include/common.h b/src/include/common.h
index 69755e24..74137967 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -312,4 +312,14 @@ struct _MetaButtonLayout
(ycoord) >= (rect).y && \
(ycoord) < ((rect).y + (rect).height))
+/*
+ * Placement mode
+ */
+typedef enum
+{
+ META_PLACEMENT_MODE_AUTOMATIC,
+ META_PLACEMENT_MODE_POINTER,
+ META_PLACEMENT_MODE_MANUAL
+} MetaPlacementMode;
+
#endif
diff --git a/src/include/prefs.h b/src/include/prefs.h
index d804207c..a2fbbf55 100644
--- a/src/include/prefs.h
+++ b/src/include/prefs.h
@@ -64,7 +64,8 @@ typedef enum
META_PREF_RESIZE_WITH_RIGHT_BUTTON,
META_PREF_CENTER_NEW_WINDOWS,
META_PREF_SIDE_BY_SIDE_TILING,
- META_PREF_FORCE_FULLSCREEN
+ META_PREF_FORCE_FULLSCREEN,
+ META_PREF_PLACEMENT_MODE
} MetaPreference;
typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -112,6 +113,8 @@ MetaActionTitlebar meta_prefs_get_action_double_click_titlebar (void);
MetaActionTitlebar meta_prefs_get_action_middle_click_titlebar (void);
MetaActionTitlebar meta_prefs_get_action_right_click_titlebar (void);
+MetaPlacementMode meta_prefs_get_placement_mode (void);
+
void meta_prefs_set_num_workspaces (int n_workspaces);
const char* meta_prefs_get_workspace_name (int i);
diff --git a/src/org.mate.marco.gschema.xml b/src/org.mate.marco.gschema.xml
index 4108355c..6bd57811 100644
--- a/src/org.mate.marco.gschema.xml
+++ b/src/org.mate.marco.gschema.xml
@@ -30,6 +30,11 @@
<value nick="menu" value="7"/>
<value nick="last" value="8"/>
</enum>
+ <enum id="org.mate.Marco.placement_type">
+ <value value="0" nick="automatic"/>
+ <value value="1" nick="pointer"/>
+ <value value="2" nick="manual"/>
+ </enum>
<schema id="org.mate.Marco" path="/org/mate/marco/">
<child name="general" schema="org.mate.Marco.general"/>
@@ -171,6 +176,11 @@
<summary>Whether to enable side-by-side tiling</summary>
<description>If enabled, dropping windows on screen edges maximizes them vertically and resizes them horizontally to cover half of the available area. Drag-dropping to the top maximizes the window.</description>
</key>
+ <key name="placement-mode" enum="org.mate.Marco.placement_type">
+ <default>'automatic'</default>
+ <summary>Window placement mode</summary>
+ <description>The window placement mode indicates how new windows are positioned. "automatic" means the system chooses a location automatically based on the space available on the desktop, or by a simple cascade if there is no space; "pointer" means that new windows are placed according to the mouse pointer position; "manual" means that the user must manually place the new window with the mouse or keyboard.</description>
+ </key>
</schema>
<schema id="org.mate.Marco.workspace-names" path="/org/mate/marco/workspace-names/">