diff --git a/src/core/keybindings.c b/src/core/keybindings.c index ef36cff77..f2ef07697 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -2239,7 +2239,10 @@ process_mouse_move_resize_grab (MetaDisplay *display, if (window->shaken_loose || tile_mode == META_TILE_MAXIMIZED) meta_window_maximize (window, META_MAXIMIZE_BOTH); else if (tile_mode != META_TILE_NONE) - meta_window_tile (window, tile_mode); + meta_window_restore_tile (window, + tile_mode, + display->grab_initial_window_pos.width, + display->grab_initial_window_pos.height); else meta_window_move_resize_frame (display->grab_window, TRUE, diff --git a/src/core/window-private.h b/src/core/window-private.h index 443bcf4d8..a4b03eae5 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -207,6 +207,8 @@ struct _MetaWindow int tile_monitor_number; int preferred_output_winsys_id; + double tile_hfraction; + /* Whether we're shaded */ guint shaded : 1; @@ -557,7 +559,7 @@ struct _MetaWindowClass #define META_WINDOW_TILED_MAXIMIZED(w)(META_WINDOW_MAXIMIZED(w) && \ (w)->tile_mode == META_TILE_MAXIMIZED) #define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen) -#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !META_WINDOW_TILED_SIDE_BY_SIDE(w) && !(w)->fullscreen && !(w)->shaded) +#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && !(w)->fullscreen && !(w)->shaded) #define META_WINDOW_ALLOWS_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && \ (((w)->size_hints.min_width < (w)->size_hints.max_width) || \ ((w)->size_hints.min_height < (w)->size_hints.max_height))) @@ -579,6 +581,10 @@ void meta_window_queue (MetaWindow *window, guint queuebits); void meta_window_tile (MetaWindow *window, MetaTileMode mode); +void meta_window_restore_tile (MetaWindow *window, + MetaTileMode mode, + int width, + int height); void meta_window_maximize_internal (MetaWindow *window, MetaMaximizeFlags directions, MetaRectangle *saved_rect); diff --git a/src/core/window.c b/src/core/window.c index d4fb40456..09f6fd3d0 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1017,6 +1017,7 @@ _meta_window_shared_new (MetaDisplay *display, window->on_all_workspaces_requested = FALSE; window->tile_mode = META_TILE_NONE; window->tile_monitor_number = -1; + window->tile_hfraction = -1.; window->shaded = FALSE; window->initially_iconic = FALSE; window->minimized = FALSE; @@ -2968,6 +2969,42 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window) return window->bypass_compositor == _NET_WM_BYPASS_COMPOSITOR_HINT_OFF; } +static void +meta_window_get_tile_fraction (MetaWindow *window, + MetaTileMode tile_mode, + double *fraction) +{ + if (tile_mode == META_TILE_NONE) + *fraction = -1.; + else if (tile_mode == META_TILE_MAXIMIZED) + *fraction = 1.; + else if (META_WINDOW_TILED_SIDE_BY_SIDE (window)) + { + if (window->tile_mode != tile_mode) + *fraction = 1. - window->tile_hfraction; + else + *fraction = window->tile_hfraction; + } + else + *fraction = .5; +} + +static void +meta_window_update_tile_fraction (MetaWindow *window, + int new_w, + int new_h) +{ + MetaRectangle work_area; + + if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) + return; + + meta_window_get_work_area_for_monitor (window, + window->tile_monitor_number, + &work_area); + window->tile_hfraction = (double)new_w / work_area.width; +} + void meta_window_tile (MetaWindow *window, MetaTileMode tile_mode) @@ -2975,6 +3012,7 @@ meta_window_tile (MetaWindow *window, MetaMaximizeFlags directions; MetaRectangle old_frame_rect, old_buffer_rect; + meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction); window->tile_mode = tile_mode; /* Don't do anything if no tiling is requested */ @@ -3007,6 +3045,16 @@ meta_window_tile (MetaWindow *window, meta_frame_queue_draw (window->frame); } +void +meta_window_restore_tile (MetaWindow *window, + MetaTileMode mode, + int width, + int height) +{ + meta_window_update_tile_fraction (window, width, height); + meta_window_tile (window, mode); +} + static gboolean meta_window_can_tile_maximized (MetaWindow *window) { @@ -4026,6 +4074,9 @@ meta_window_resize_frame_with_gravity (MetaWindow *window, rect.width = w; rect.height = h; + if (user_op) + meta_window_update_tile_fraction (window, w, h); + flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_RESIZE_ACTION; meta_window_move_resize_internal (window, flags, gravity, rect); } @@ -6349,19 +6400,22 @@ meta_window_get_tile_area (MetaWindow *window, MetaTileMode tile_mode, MetaRectangle *tile_area) { + MetaRectangle work_area; int tile_monitor_number; + double fraction; g_return_if_fail (tile_mode != META_TILE_NONE); tile_monitor_number = meta_window_get_current_tile_monitor_number (window); - meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area); + meta_window_get_work_area_for_monitor (window, tile_monitor_number, &work_area); + meta_window_get_tile_fraction (window, tile_mode, &fraction); - if (tile_mode == META_TILE_LEFT || tile_mode == META_TILE_RIGHT) - tile_area->width /= 2; + *tile_area = work_area; + tile_area->width = round (tile_area->width * fraction); if (tile_mode == META_TILE_RIGHT) - tile_area->x += tile_area->width; + tile_area->x += work_area.width - tile_area->width; } gboolean diff --git a/src/ui/frames.c b/src/ui/frames.c index 2d862545b..129a9e59b 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -1621,6 +1621,9 @@ get_control (MetaUIFrame *frame, int root_x, int root_y) has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0; has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0; + if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT) + has_vert = has_horiz = FALSE; + if (POINT_IN_RECT (x, y, fgeom.title_rect)) { if (has_vert && y <= TOP_RESIZE_HEIGHT && has_north_resize) @@ -1693,12 +1696,12 @@ get_control (MetaUIFrame *frame, int root_x, int root_y) } else if (x <= fgeom.borders.total.left) { - if (has_horiz) + if (has_horiz || flags & META_FRAME_TILED_RIGHT) return META_FRAME_CONTROL_RESIZE_W; } else if (x >= (fgeom.width - fgeom.borders.total.right)) { - if (has_horiz) + if (has_horiz || flags & META_FRAME_TILED_LEFT) return META_FRAME_CONTROL_RESIZE_E; }