diff --git a/src/core/constraints.c b/src/core/constraints.c index e0e3490cf..9247ce6cd 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -97,7 +97,7 @@ typedef enum PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1, PRIORITY_SIZE_HINTS_INCREMENTS = 1, PRIORITY_MAXIMIZATION = 2, - PRIORITY_CONSTRAINED_EDGES = 2, + PRIORITY_TILING = 2, PRIORITY_FULLSCREEN = 2, PRIORITY_SIZE_HINTS_LIMITS = 3, PRIORITY_TITLEBAR_VISIBLE = 4, @@ -152,10 +152,6 @@ static gboolean constrain_maximization (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, gboolean check_only); -static gboolean constrain_constrained_edges (MetaWindow *window, - ConstraintInfo *info, - ConstraintPriority priority, - gboolean check_only); static gboolean constrain_fullscreen (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, @@ -213,7 +209,6 @@ typedef struct { static const Constraint all_constraints[] = { {constrain_modal_dialog, "constrain_modal_dialog"}, {constrain_maximization, "constrain_maximization"}, - {constrain_constrained_edges, "constrain_constrained_edges"}, {constrain_fullscreen, "constrain_fullscreen"}, {constrain_size_increments, "constrain_size_increments"}, {constrain_size_limits, "constrain_size_limits"}, @@ -803,45 +798,6 @@ constrain_fullscreen (MetaWindow *window, return TRUE; } -static gboolean -constrain_constrained_edges (MetaWindow *window, - ConstraintInfo *info, - ConstraintPriority priority, - gboolean check_only) -{ - MetaRectangle monitor, new_rectangle; - gboolean constraint_already_satisfied; - - if (priority > PRIORITY_CONSTRAINED_EDGES) - return TRUE; - - /* Determine whether constraint applies; exit if it doesn't */ - if (!window->constrained_edges) - return TRUE; - - new_rectangle = info->current; - monitor = info->work_area_monitor; - - if (window->constrained_edges & META_DIRECTION_LEFT) - new_rectangle.x = monitor.x; - if (window->constrained_edges & META_DIRECTION_RIGHT) - new_rectangle.x = monitor.x + monitor.width - new_rectangle.width; - if (window->constrained_edges & META_DIRECTION_TOP) - new_rectangle.y = monitor.y; - if (window->constrained_edges & META_DIRECTION_BOTTOM) - new_rectangle.y = monitor.y + monitor.height - new_rectangle.height; - - constraint_already_satisfied = - meta_rectangle_equal (&info->current, &new_rectangle); - - if (check_only || constraint_already_satisfied) - return constraint_already_satisfied; - - /*** Enforce constraint ***/ - info->current = new_rectangle; - return TRUE; -} - static gboolean constrain_size_increments (MetaWindow *window, ConstraintInfo *info, diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 6bfa69f67..adeb9bd8e 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2936,7 +2936,6 @@ handle_toggle_tiled_left (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - meta_window_tile (window, META_TILE_ZONE_W); } static void @@ -2947,7 +2946,6 @@ handle_toggle_tiled_right (MetaDisplay *display, MetaKeyBinding *binding, gpointer dummy) { - meta_window_tile (window, META_TILE_ZONE_E); } static void diff --git a/src/core/screen-private.h b/src/core/screen-private.h index 76ce2f274..438d1f4cc 100644 --- a/src/core/screen-private.h +++ b/src/core/screen-private.h @@ -57,13 +57,7 @@ struct _MetaScreen MetaRectangle rect; /* Size of screen; rect.x & rect.y are always 0 */ MetaUI *ui; - struct { - gboolean exists; - guint timeout_id; - MetaWindow *window; - MetaRectangle area; - int monitor; - } tile_preview; + guint tile_preview_timeout_id; MetaWorkspace *active_workspace; @@ -142,12 +136,9 @@ void meta_screen_foreach_window (MetaScreen *scree void meta_screen_update_cursor (MetaScreen *screen); -void meta_screen_update_tile_preview (MetaScreen *screen, - MetaWindow *window, - MetaRectangle area, - int monitor, - gboolean delay); -void meta_screen_hide_tile_preview (MetaScreen *screen); +void meta_screen_update_tile_preview (MetaScreen *screen, + gboolean delay); +void meta_screen_hide_tile_preview (MetaScreen *screen); MetaWindow* meta_screen_get_mouse_window (MetaScreen *screen, MetaWindow *not_this_one); diff --git a/src/core/screen.c b/src/core/screen.c index 6a5eebfbd..14193d41b 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -723,6 +723,8 @@ meta_screen_new (MetaDisplay *display, screen->ui = meta_ui_new (screen->display->xdisplay, screen->xscreen); + screen->tile_preview_timeout_id = 0; + screen->stack = meta_stack_new (screen); screen->stack_tracker = meta_stack_tracker_new (screen); @@ -839,8 +841,8 @@ meta_screen_free (MetaScreen *screen, g_free (screen->monitor_infos); - if (screen->tile_preview.timeout_id) - g_source_remove (screen->tile_preview.timeout_id); + if (screen->tile_preview_timeout_id) + g_source_remove (screen->tile_preview_timeout_id); g_free (screen->screen_name); @@ -1318,69 +1320,43 @@ meta_screen_set_cursor (MetaScreen *screen, static gboolean meta_screen_update_tile_preview_timeout (gpointer data) { - MetaScreen *screen = data; - - screen->tile_preview.timeout_id = 0; - - if (screen->tile_preview.exists) - { - meta_compositor_show_tile_preview (screen->display->compositor, - screen->tile_preview.window, - &screen->tile_preview.area, - screen->tile_preview.monitor); - } - else - { - meta_compositor_hide_tile_preview (screen->display->compositor); - } - return FALSE; } #define TILE_PREVIEW_TIMEOUT_MS 200 void -meta_screen_update_tile_preview (MetaScreen *screen, - MetaWindow *window, - MetaRectangle area, - int monitor, - gboolean delay) +meta_screen_update_tile_preview (MetaScreen *screen, + gboolean delay) { - screen->tile_preview.exists = TRUE; - screen->tile_preview.window = window; - screen->tile_preview.area = area; - screen->tile_preview.monitor = monitor; - if (delay) { - if (screen->tile_preview.timeout_id > 0) + if (screen->tile_preview_timeout_id > 0) return; - screen->tile_preview.timeout_id = + screen->tile_preview_timeout_id = g_timeout_add (TILE_PREVIEW_TIMEOUT_MS, meta_screen_update_tile_preview_timeout, screen); - g_source_set_name_by_id (screen->tile_preview.timeout_id, + g_source_set_name_by_id (screen->tile_preview_timeout_id, "[mutter] meta_screen_update_tile_preview_timeout"); } else { - if (screen->tile_preview.timeout_id > 0) - g_source_remove (screen->tile_preview.timeout_id); + if (screen->tile_preview_timeout_id > 0) + g_source_remove (screen->tile_preview_timeout_id); - meta_screen_update_tile_preview_timeout ((gpointer) screen); + meta_screen_update_tile_preview_timeout ((gpointer)screen); } } void meta_screen_hide_tile_preview (MetaScreen *screen) { - screen->tile_preview.exists = FALSE; + if (screen->tile_preview_timeout_id > 0) + g_source_remove (screen->tile_preview_timeout_id); - if (screen->tile_preview.timeout_id > 0) - g_source_remove (screen->tile_preview.timeout_id); - - meta_screen_update_tile_preview_timeout ((gpointer) screen); + meta_compositor_hide_tile_preview (screen->display->compositor); } MetaWindow* diff --git a/src/core/window-private.h b/src/core/window-private.h index f4eb4685a..7a2e5d890 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -450,10 +450,8 @@ struct _MetaWindow /* This is where we store data while in another state. The information * above in MetaWindow is always the current state of the window. */ struct { - MetaWindowSizeState normal, tiled, maximized; + MetaWindowSizeState normal, maximized; } size_states; - - MetaDirection constrained_edges; }; struct _MetaWindowClass @@ -619,6 +617,7 @@ void meta_window_update_for_monitors_changed (MetaWindow *window); void meta_window_on_all_workspaces_changed (MetaWindow *window); gboolean meta_window_should_attach_to_parent (MetaWindow *window); +gboolean meta_window_can_tile_side_by_side (MetaWindow *window); gboolean meta_window_updates_are_frozen (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index 976deda01..34a36259f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2609,8 +2609,6 @@ get_current_size_state (MetaWindow *window) { if (META_WINDOW_MAXIMIZED (window)) return &window->size_states.maximized; - else if (window->constrained_edges != 0) - return &window->size_states.tiled; else return &window->size_states.normal; } @@ -2882,48 +2880,35 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window) return window->bypass_compositor == _NET_WM_BYPASS_COMPOSITOR_HINT_OFF; } -static void -get_tile_zone_area (MetaWindow *window, - MetaTileZone tile_zone, - MetaRectangle *rect_p) +static gboolean +meta_window_can_tile_maximized (MetaWindow *window) { - MetaRectangle work_area; - meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area); + return window->has_maximize_func; +} - MetaRectangle rect = { - .x = work_area.x, - .y = work_area.y, - }; +gboolean +meta_window_can_tile_side_by_side (MetaWindow *window) +{ + int monitor; + MetaRectangle tile_area; + MetaRectangle client_rect; - switch (tile_zone & META_DIRECTION_HORIZONTAL) - { - case META_DIRECTION_HORIZONTAL: - rect.width = work_area.width; - break; - case META_DIRECTION_LEFT: - rect.width = work_area.width / 2; - break; - case META_DIRECTION_RIGHT: - rect.x += work_area.width / 2; - rect.width = work_area.width / 2; - break; - } + if (!meta_window_can_tile_maximized (window)) + return FALSE; - switch (tile_zone & META_DIRECTION_VERTICAL) - { - case META_DIRECTION_VERTICAL: - rect.height = work_area.height; - break; - case META_DIRECTION_TOP: - rect.height = work_area.height / 2; - break; - case META_DIRECTION_BOTTOM: - rect.y += work_area.height / 2; - rect.height = work_area.height / 2; - break; - } + monitor = meta_screen_get_current_monitor (window->screen); + meta_window_get_work_area_for_monitor (window, monitor, &tile_area); - *rect_p = rect; + /* Do not allow tiling in portrait orientation */ + if (tile_area.height > tile_area.width) + return FALSE; + + tile_area.width /= 2; + + meta_window_frame_rect_to_client_rect (window, &tile_area, &client_rect); + + return client_rect.width >= window->size_hints.min_width && + client_rect.height >= window->size_hints.min_height; } static void @@ -3037,10 +3022,7 @@ meta_window_unmaximize (MetaWindow *window, g_assert (unmaximize_horizontally || unmaximize_vertically); MetaWindowSizeState *size_state; - if (window->constrained_edges != 0) - size_state = &window->size_states.tiled; - else - size_state = &window->size_states.normal; + size_state = &window->size_states.normal; /* Special-case unmaximizing both directions to restoring the * last state. This makes the unmaximize buttons go back to the @@ -3103,12 +3085,6 @@ meta_window_unmaximize (MetaWindow *window, new_size_state.rect = target_rect; - /* Clear any constrained edges when unmaximizing */ - if (unmaximize_horizontally) - window->constrained_edges &= ~META_DIRECTION_HORIZONTAL; - if (unmaximize_vertically) - window->constrained_edges &= ~META_DIRECTION_VERTICAL; - meta_window_unmaximize_internal (window, &new_size_state); } } @@ -5509,119 +5485,6 @@ update_move_timeout (gpointer data) return FALSE; } -typedef enum { - META_RECT_EDGE_W = 1 << 0, /* west */ - META_RECT_EDGE_E = 1 << 1, /* east */ - META_RECT_EDGE_H = 1 << 2, /* horizontal (middle) */ - META_RECT_EDGE_N = 1 << 3, /* north */ - META_RECT_EDGE_S = 1 << 4, /* south */ - META_RECT_EDGE_V = 1 << 5, /* vertical (middle) */ -} MetaRectEdges; - -typedef struct { - int x1, y1, x2, y2; -} Box; - -static MetaRectEdges -get_rect_edges (Box outer, Box inner, int x, int y) -{ - MetaDirection edges = 0; - - if (x >= outer.x1 && x < inner.x1) - edges |= META_RECT_EDGE_W; - else if (x >= inner.x2 && x < outer.x2) - edges |= META_RECT_EDGE_E; - else if (x >= inner.x1 && x < inner.x2) - edges |= META_RECT_EDGE_H; - - if (y >= outer.y1 && y < inner.y1) - edges |= META_RECT_EDGE_N; - else if (y >= inner.y2 && y < outer.y2) - edges |= META_RECT_EDGE_S; - else if (y >= inner.y1 && y < inner.y2) - edges |= META_RECT_EDGE_V; - - return edges; -} - -static inline Box -box_from_rect (MetaRectangle rect) -{ - Box box = { .x1 = rect.x, .y1 = rect.y, .x2 = rect.x + rect.width, .y2 = rect.y + rect.height }; - return box; -} - -static inline int -get_drag_shake_threshold (void) -{ - /* Originally for detaching maximized windows, but we use this - * for the zones at the sides of the monitor where trigger tiling - * because it's about the right size - */ -#define DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR 6 - return meta_prefs_get_drag_threshold () * DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR; -} - -static MetaTileZone -get_tile_zone_for_pointer (MetaWindow *window, - int x, int y) -{ - if (!window->has_maximize_func) - return 0; - - const MetaMonitorInfo *monitor; - MetaRectangle work_area; - monitor = meta_screen_get_current_monitor_info_for_pos (window->screen, x, y); - meta_window_get_work_area_for_monitor (window, monitor->number, &work_area); - - MetaRectangle client_rect; - meta_window_frame_rect_to_client_rect (window, &work_area, &client_rect); - - gboolean can_tile_horz = ((client_rect.width / 2) >= window->size_hints.min_width); - gboolean can_tile_vert = ((client_rect.height / 2) >= window->size_hints.min_height); - gboolean can_max_horz = (client_rect.width >= window->size_hints.min_width); - gboolean can_max_vert = (client_rect.height >= window->size_hints.min_height); - - int shake_threshold = get_drag_shake_threshold (); - Box outer = box_from_rect (monitor->rect); - /* fudge the work area with the shake threshold */ - Box inner = box_from_rect (work_area); - inner.x1 = MAX (inner.x1, shake_threshold); - inner.x2 = MIN (outer.x2 - shake_threshold, inner.x2); - inner.y1 = MAX (inner.y1, shake_threshold); - inner.y2 = MIN (outer.y2 - shake_threshold, inner.y2); - - MetaRectEdges edges = get_rect_edges (outer, inner, x, y); - - /* Simple cases: outside of a monitor, or in the inner rectangle - * entirely aren't tile zones. */ - if (edges == 0 || - edges == (META_RECT_EDGE_H | META_RECT_EDGE_V)) - return 0; - - /* Special case: the top border is maximization */ - if (edges == (META_RECT_EDGE_N | META_RECT_EDGE_H)) - return META_TILE_ZONE_MAXIMIZED; - - MetaTileZone tile_zone = 0; - - if ((edges & META_RECT_EDGE_W) && can_tile_horz) - tile_zone |= META_DIRECTION_LEFT; - else if ((edges & META_RECT_EDGE_E) && can_tile_horz) - tile_zone |= META_DIRECTION_RIGHT; - else if ((edges & META_RECT_EDGE_H) && can_max_horz) - tile_zone |= META_DIRECTION_HORIZONTAL; - - if ((edges & META_RECT_EDGE_N) && can_tile_vert) - tile_zone |= META_DIRECTION_TOP; - else if ((edges & META_RECT_EDGE_S) && can_tile_vert) - tile_zone |= META_DIRECTION_BOTTOM; - else if ((edges & META_RECT_EDGE_V) && can_max_vert) - tile_zone |= META_DIRECTION_VERTICAL; - - return tile_zone; -} - static void update_move (MetaWindow *window, gboolean snap, @@ -5658,36 +5521,20 @@ update_move (MetaWindow *window, if (dx == 0 && dy == 0) return; - shake_threshold = get_drag_shake_threshold (); + /* Originally for detaching maximized windows, but we use this + * for the zones at the sides of the monitor where trigger tiling + * because it's about the right size + */ +#define DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR 6 + shake_threshold = meta_prefs_get_drag_threshold () * + DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR; /* shake loose (unmaximize) maximized or tiled window if dragged beyond * the threshold in the Y direction. Tiled windows can also be pulled * loose via X motion. */ - int shake_x_threshold = G_MAXINT; - if ((window->constrained_edges & META_DIRECTION_HORIZONTAL) && - (window->constrained_edges & META_DIRECTION_HORIZONTAL) != META_DIRECTION_HORIZONTAL) - shake_x_threshold = shake_threshold; - - if (meta_prefs_get_edge_tiling ()) - { - MetaTileZone tile_zone = get_tile_zone_for_pointer (window, x, y); - if (tile_zone != 0) - { - MetaRectangle tile_area; - get_tile_zone_area (window, tile_zone, &tile_area); - const MetaMonitorInfo *monitor = meta_screen_get_current_monitor_info_for_pos (window->screen, x, y); - meta_screen_update_tile_preview (window->screen, window, tile_area, monitor->number, TRUE); - } - else - { - meta_screen_hide_tile_preview (window->screen); - } - } - - if ((META_WINDOW_MAXIMIZED (window) || window->constrained_edges) && - (ABS (dy) >= shake_threshold || ABS (dx) >= shake_x_threshold)) + if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold)) { double prop; @@ -5717,8 +5564,6 @@ update_move (MetaWindow *window, window->size_states.normal.rect.x = display->grab_initial_window_pos.x; window->size_states.normal.rect.y = display->grab_initial_window_pos.y; - window->constrained_edges = 0; - meta_window_unmaximize_internal (window, &window->size_states.normal); return; } @@ -5973,10 +5818,6 @@ end_grab_op (MetaWindow *window, update_move (window, modifiers & CLUTTER_SHIFT_MASK, x, y); - - MetaTileZone tile_zone = get_tile_zone_for_pointer (window, x, y); - if (tile_zone != 0) - meta_window_tile (window, tile_zone); } else if (meta_grab_op_is_resizing (window->display->grab_op)) { @@ -5986,9 +5827,6 @@ end_grab_op (MetaWindow *window, TRUE); } } - - meta_screen_hide_tile_preview (window->screen); - meta_display_end_grab_op (window->display, clutter_event_get_time (event)); } @@ -7805,36 +7643,3 @@ meta_window_emit_size_changed (MetaWindow *window) { g_signal_emit (window, window_signals[SIZE_CHANGED], 0); } - -void -meta_window_tile (MetaWindow *window, - MetaTileZone tile_zone) -{ - /* Special case: Tile maximizing is the same as maximizing. */ - if (tile_zone == META_TILE_ZONE_MAXIMIZED) - { - meta_window_maximize (window, META_MAXIMIZE_BOTH); - return; - } - - MetaWindowSizeState *size_state = get_current_size_state (window); - save_size_state (window, size_state, &window->rect); - - window->constrained_edges = tile_zone; - - if ((window->constrained_edges & META_DIRECTION_VERTICAL) == META_DIRECTION_VERTICAL) - window->maximized_vertically = TRUE; - if ((window->constrained_edges & META_DIRECTION_HORIZONTAL) == META_DIRECTION_HORIZONTAL) - window->maximized_horizontally = TRUE; - - meta_window_recalc_features (window); - set_net_wm_state (window); - - MetaRectangle target_rect; - get_tile_zone_area (window, tile_zone, &target_rect); - - meta_window_move_resize_internal (window, - META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED, - NorthWestGravity, - target_rect); -} diff --git a/src/meta/common.h b/src/meta/common.h index 19bbc3c56..a18be7f45 100644 --- a/src/meta/common.h +++ b/src/meta/common.h @@ -317,26 +317,6 @@ typedef enum META_DIRECTION_VERTICAL = META_DIRECTION_UP | META_DIRECTION_DOWN, } MetaDirection; -/* Tile zones are specified in terms of their constrained edges. - * So, "top left corner" is top and left, which should be obvious, - * but "left side of the screen" is top, bottom, and left - */ -typedef enum { - META_TILE_ZONE_MAXIMIZED_HORZ = META_DIRECTION_HORIZONTAL, - META_TILE_ZONE_MAXIMIZED_VERT = META_DIRECTION_VERTICAL, - META_TILE_ZONE_MAXIMIZED = META_TILE_ZONE_MAXIMIZED_HORZ | META_TILE_ZONE_MAXIMIZED_VERT, - - META_TILE_ZONE_W = META_TILE_ZONE_MAXIMIZED_VERT | META_DIRECTION_LEFT, - META_TILE_ZONE_E = META_TILE_ZONE_MAXIMIZED_VERT | META_DIRECTION_RIGHT, - META_TILE_ZONE_N = META_TILE_ZONE_MAXIMIZED_HORZ | META_DIRECTION_TOP, - META_TILE_ZONE_S = META_TILE_ZONE_MAXIMIZED_HORZ | META_DIRECTION_BOTTOM, - - META_TILE_ZONE_NW = META_DIRECTION_TOP | META_DIRECTION_LEFT, - META_TILE_ZONE_NE = META_DIRECTION_TOP | META_DIRECTION_RIGHT, - META_TILE_ZONE_SW = META_DIRECTION_BOTTOM | META_DIRECTION_LEFT, - META_TILE_ZONE_SE = META_DIRECTION_BOTTOM | META_DIRECTION_RIGHT, -} MetaTileZone; - /** * MetaMotionDirection: * @META_MOTION_UP: Upwards motion diff --git a/src/meta/window.h b/src/meta/window.h index a5b8da9dd..a3a4b768a 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -258,7 +258,4 @@ gboolean meta_window_is_client_decorated (MetaWindow *window); gboolean meta_window_titlebar_is_onscreen (MetaWindow *window); void meta_window_shove_titlebar_onscreen (MetaWindow *window); -void meta_window_tile (MetaWindow *window, - MetaTileZone tile_zone); - #endif