diff options
| -rw-r--r-- | src/core/place.c | 52 | ||||
| -rw-r--r-- | src/core/prefs.c | 16 | ||||
| -rw-r--r-- | src/core/window-private.h | 3 | ||||
| -rw-r--r-- | src/core/window.c | 8 | ||||
| -rw-r--r-- | src/include/common.h | 10 | ||||
| -rw-r--r-- | src/include/prefs.h | 5 | ||||
| -rw-r--r-- | src/org.mate.marco.gschema.xml | 10 | 
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/">  | 
