Compare commits
	
		
			14 Commits
		
	
	
		
			main
			...
			wip/fmuell
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 446c9b7460 | ||
|   | 437ab625ed | ||
|   | d89d5af040 | ||
|   | 5a95e5c80a | ||
|   | 211669ba47 | ||
|   | db5795a7cd | ||
|   | d3527bf99e | ||
|   | 94f5a161f9 | ||
|   | 209407657d | ||
|   | ff34e51826 | ||
|   | 5b5d8676d4 | ||
|   | a2dcf44c60 | ||
|   | ff0eee4331 | ||
|   | 0726d93e79 | 
| @@ -943,7 +943,7 @@ constrain_maximization (MetaWindow         *window, | ||||
|   /* Calculate target_size = maximized size of (window + frame) */ | ||||
|   if (META_WINDOW_TILED_MAXIMIZED (window)) | ||||
|     { | ||||
|       meta_window_get_current_tile_area (window, &target_size); | ||||
|       meta_window_get_tile_area (window, window->tile_mode, &target_size); | ||||
|     } | ||||
|   else if (META_WINDOW_MAXIMIZED (window)) | ||||
|     { | ||||
| @@ -1030,7 +1030,7 @@ constrain_tiling (MetaWindow         *window, | ||||
|   /* Calculate target_size - as the tile previews need this as well, we | ||||
|    * use an external function for the actual calculation | ||||
|    */ | ||||
|   meta_window_get_current_tile_area (window, &target_size); | ||||
|   meta_window_get_tile_area (window, window->tile_mode, &target_size); | ||||
|  | ||||
|   /* Check min size constraints; max size constraints are ignored as for | ||||
|    * maximized windows. | ||||
|   | ||||
| @@ -556,7 +556,7 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|  | ||||
|   edge_data = display->grab_edge_resistance_data; | ||||
|  | ||||
|   if (auto_snap) | ||||
|   if (auto_snap && !META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|     { | ||||
|       /* Do the auto snapping instead of normal edge resistance; in all | ||||
|        * cases, we allow snapping to opposite kinds of edges (e.g. left | ||||
| @@ -591,6 +591,50 @@ apply_edge_resistance_to_each_side (MetaDisplay         *display, | ||||
|                                         FALSE, | ||||
|                                         keyboard_op); | ||||
|     } | ||||
|   else if (auto_snap && META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|     { | ||||
|       MetaRectangle workarea; | ||||
|       guint i; | ||||
|  | ||||
|       const gfloat tile_edges[] = | ||||
|         { | ||||
|           1./4., | ||||
|           1./3., | ||||
|           1./2., | ||||
|           2./3., | ||||
|           3./4., | ||||
|         }; | ||||
|  | ||||
|       meta_window_get_work_area_current_monitor (window, &workarea); | ||||
|  | ||||
|       new_left = new_outer->x; | ||||
|       new_top = new_outer->y; | ||||
|       new_right = new_outer->x + new_outer->width; | ||||
|       new_bottom = new_outer->y + new_outer->height; | ||||
|  | ||||
|       /* When snapping tiled windows, we don't really care about the | ||||
|        * x and y position, only about the width and height. Also, it | ||||
|        * is special-cased (instead of relying on edge_data) because | ||||
|        * we don't really care for other windows when calculating the | ||||
|        * snapping points of tiled windows - we only care about the | ||||
|        * work area and the target position. | ||||
|        */ | ||||
|       for (i = 0; i < G_N_ELEMENTS (tile_edges); i++) | ||||
|         { | ||||
|           guint horizontal_point = workarea.x + floor (workarea.width * tile_edges[i]); | ||||
|  | ||||
|           if (ABS (horizontal_point - new_left) < 16) | ||||
|             { | ||||
|               new_left = horizontal_point; | ||||
|               new_right = workarea.x + workarea.width; | ||||
|             } | ||||
|           else if (ABS (horizontal_point - new_right) < 16) | ||||
|             { | ||||
|               new_left = workarea.x; | ||||
|               new_right = horizontal_point; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Disable edge resistance for resizes when windows have size | ||||
| @@ -1223,7 +1267,6 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
| { | ||||
|   MetaRectangle old_outer, new_outer; | ||||
|   int proposed_outer_width, proposed_outer_height; | ||||
|   gboolean is_resize; | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &old_outer); | ||||
|   proposed_outer_width  = *new_width; | ||||
| @@ -1235,7 +1278,6 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|                                       proposed_outer_height); | ||||
|  | ||||
|   window->display->grab_last_user_action_was_snap = snap; | ||||
|   is_resize = TRUE; | ||||
|   if (apply_edge_resistance_to_each_side (window->display, | ||||
|                                           window, | ||||
|                                           &old_outer, | ||||
| @@ -1243,7 +1285,7 @@ meta_window_edge_resistance_for_resize (MetaWindow  *window, | ||||
|                                           timeout_func, | ||||
|                                           snap, | ||||
|                                           is_keyboard_op, | ||||
|                                           is_resize)) | ||||
|                                           TRUE)) | ||||
|     { | ||||
|       *new_width = new_outer.width; | ||||
|       *new_height = new_outer.height; | ||||
|   | ||||
| @@ -2221,12 +2221,14 @@ process_mouse_move_resize_grab (MetaDisplay     *display, | ||||
|  | ||||
|   if (event->keyval == CLUTTER_KEY_Escape) | ||||
|     { | ||||
|       MetaTileMode tile_mode; | ||||
|  | ||||
|       /* Hide the tiling preview if necessary */ | ||||
|       if (window->tile_mode != META_TILE_NONE) | ||||
|       if (screen->preview_tile_mode != META_TILE_NONE) | ||||
|         meta_screen_hide_tile_preview (screen); | ||||
|  | ||||
|       /* Restore the original tile mode */ | ||||
|       window->tile_mode = display->grab_tile_mode; | ||||
|       tile_mode = display->grab_tile_mode; | ||||
|       window->tile_monitor_number = display->grab_tile_monitor_number; | ||||
|  | ||||
|       /* End move or resize and restore to original state.  If the | ||||
| @@ -2234,10 +2236,13 @@ process_mouse_move_resize_grab (MetaDisplay     *display, | ||||
|        * need to remaximize it.  In normal cases, we need to do a | ||||
|        * moveresize now to get the position back to the original. | ||||
|        */ | ||||
|       if (window->shaken_loose || window->tile_mode == META_TILE_MAXIMIZED) | ||||
|       if (window->shaken_loose || tile_mode == META_TILE_MAXIMIZED) | ||||
|         meta_window_maximize (window, META_MAXIMIZE_BOTH); | ||||
|       else if (window->tile_mode != META_TILE_NONE) | ||||
|         meta_window_tile (window); | ||||
|       else if (tile_mode != META_TILE_NONE) | ||||
|         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, | ||||
| @@ -3184,7 +3189,6 @@ handle_toggle_tiled (MetaDisplay     *display, | ||||
|   else if (meta_window_can_tile_side_by_side (window)) | ||||
|     { | ||||
|       window->tile_monitor_number = window->monitor->number; | ||||
|       window->tile_mode = mode; | ||||
|       /* Maximization constraints beat tiling constraints, so if the window | ||||
|        * is maximized, tiling won't have any effect unless we unmaximize it | ||||
|        * horizontally first; rather than calling meta_window_unmaximize(), | ||||
| @@ -3192,7 +3196,7 @@ handle_toggle_tiled (MetaDisplay     *display, | ||||
|        * save an additional roundtrip. | ||||
|        */ | ||||
|       window->maximized_horizontally = FALSE; | ||||
|       meta_window_tile (window); | ||||
|       meta_window_tile (window, mode); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -56,6 +56,7 @@ struct _MetaScreen | ||||
|   MetaUI *ui; | ||||
|  | ||||
|   guint tile_preview_timeout_id; | ||||
|   guint preview_tile_mode : 2; | ||||
|  | ||||
|   MetaWorkspace *active_workspace; | ||||
|  | ||||
|   | ||||
| @@ -308,6 +308,7 @@ set_supported_hint (MetaScreen *screen) | ||||
|  | ||||
|     screen->display->atom__GTK_FRAME_EXTENTS, | ||||
|     screen->display->atom__GTK_SHOW_WINDOW_MENU, | ||||
|     screen->display->atom__GTK_EDGE_CONSTRAINTS, | ||||
|   }; | ||||
|  | ||||
|   XChangeProperty (screen->display->xdisplay, screen->xroot, | ||||
| @@ -1410,7 +1411,7 @@ meta_screen_update_tile_preview_timeout (gpointer data) | ||||
|  | ||||
|   if (window) | ||||
|     { | ||||
|       switch (window->tile_mode) | ||||
|       switch (screen->preview_tile_mode) | ||||
|         { | ||||
|           case META_TILE_LEFT: | ||||
|           case META_TILE_RIGHT: | ||||
| @@ -1435,7 +1436,7 @@ meta_screen_update_tile_preview_timeout (gpointer data) | ||||
|       int monitor; | ||||
|  | ||||
|       monitor = meta_window_get_current_tile_monitor_number (window); | ||||
|       meta_window_get_current_tile_area (window, &tile_rect); | ||||
|       meta_window_get_tile_area (window, screen->preview_tile_mode, &tile_rect); | ||||
|       meta_compositor_show_tile_preview (screen->display->compositor, | ||||
|                                          window, &tile_rect, monitor); | ||||
|     } | ||||
| @@ -1479,6 +1480,7 @@ meta_screen_hide_tile_preview (MetaScreen *screen) | ||||
|     g_source_remove (screen->tile_preview_timeout_id); | ||||
|   screen->tile_preview_timeout_id = 0; | ||||
|  | ||||
|   screen->preview_tile_mode = META_TILE_NONE; | ||||
|   meta_compositor_hide_tile_preview (screen->display->compositor); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -129,6 +129,13 @@ typedef struct _MetaPlacementRule | ||||
|   int height; | ||||
| } MetaPlacementRule; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   META_EDGE_CONSTRAINT_NONE    = 0, | ||||
|   META_EDGE_CONSTRAINT_WINDOW  = 1, | ||||
|   META_EDGE_CONSTRAINT_MONITOR = 2, | ||||
| } MetaEdgeConstraint; | ||||
|  | ||||
| struct _MetaWindow | ||||
| { | ||||
|   GObject parent_instance; | ||||
| @@ -199,14 +206,21 @@ struct _MetaWindow | ||||
|   guint maximize_vertically_after_placement : 1; | ||||
|   guint minimize_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 */ | ||||
|   /* The current tile mode */ | ||||
|   guint tile_mode : 2; | ||||
|   /* The last "full" maximized/unmaximized state. We need to keep track of | ||||
|    * that to toggle between normal/tiled or maximized/tiled states. */ | ||||
|   guint saved_maximize : 1; | ||||
|   int tile_monitor_number; | ||||
|  | ||||
|   /* 0 - top | ||||
|    * 1 - right | ||||
|    * 2 - bottom | ||||
|    * 3 - left */ | ||||
|   MetaEdgeConstraint edge_constraints[4]; | ||||
|  | ||||
|   double tile_hfraction; | ||||
|  | ||||
|   int preferred_output_winsys_id; | ||||
|  | ||||
|   /* Whether we're shaded */ | ||||
| @@ -559,7 +573,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,7 +593,12 @@ void        meta_window_unmanage           (MetaWindow  *window, | ||||
|                                             guint32      timestamp); | ||||
| void        meta_window_queue              (MetaWindow  *window, | ||||
|                                             guint queuebits); | ||||
| void        meta_window_tile               (MetaWindow        *window); | ||||
| 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); | ||||
| @@ -648,8 +667,9 @@ void meta_window_get_work_area_for_logical_monitor (MetaWindow         *window, | ||||
|                                                     MetaRectangle      *area); | ||||
|  | ||||
| int meta_window_get_current_tile_monitor_number (MetaWindow *window); | ||||
| void meta_window_get_current_tile_area         (MetaWindow    *window, | ||||
|                                                 MetaRectangle *tile_area); | ||||
| void meta_window_get_tile_area                  (MetaWindow    *window, | ||||
|                                                  MetaTileMode   mode, | ||||
|                                                  MetaRectangle *tile_area); | ||||
|  | ||||
|  | ||||
| gboolean meta_window_same_application (MetaWindow *window, | ||||
|   | ||||
| @@ -133,6 +133,10 @@ static void set_workspace_state (MetaWindow    *window, | ||||
|                                  gboolean       on_all_workspaces, | ||||
|                                  MetaWorkspace *workspace); | ||||
|  | ||||
| static MetaWindow * meta_window_find_tile_match (MetaWindow   *window, | ||||
|                                                  MetaTileMode  mode); | ||||
| static void update_edge_constraints (MetaWindow *window); | ||||
|  | ||||
| /* Idle handlers for the three queues (run with meta_later_add()). The | ||||
|  * "data" parameter in each case will be a GINT_TO_POINTER of the | ||||
|  * index into the queue arrays to use. | ||||
| @@ -1017,6 +1021,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; | ||||
| @@ -2761,6 +2766,9 @@ meta_window_maximize_internal (MetaWindow        *window, | ||||
|   window->maximized_vertically = | ||||
|     window->maximized_vertically   || maximize_vertically; | ||||
|  | ||||
|   /* Update the edge constraints */ | ||||
|   update_edge_constraints (window);; | ||||
|  | ||||
|   meta_window_recalc_features (window); | ||||
|   set_net_wm_state (window); | ||||
|  | ||||
| @@ -2968,12 +2976,122 @@ 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) | ||||
| { | ||||
|   MetaWindow *tile_match; | ||||
|  | ||||
|   /* Make sure the tile match is up-to-date and matches the | ||||
|    * passed in mode rather than the current state | ||||
|    */ | ||||
|   tile_match = meta_window_find_tile_match (window, tile_mode); | ||||
|  | ||||
|   if (tile_mode == META_TILE_NONE) | ||||
|     *fraction = -1.; | ||||
|   else if (tile_mode == META_TILE_MAXIMIZED) | ||||
|     *fraction = 1.; | ||||
|   else if (tile_match) | ||||
|     *fraction = 1. - tile_match->tile_hfraction; | ||||
|   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) | ||||
| { | ||||
|   MetaWindow *tile_match = window->tile_match; | ||||
|   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; | ||||
|  | ||||
|   if (tile_match && window->display->grab_window == window) | ||||
|     meta_window_tile (tile_match, tile_match->tile_mode); | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_edge_constraints (MetaWindow *window) | ||||
| { | ||||
|   switch (window->tile_mode) | ||||
|     { | ||||
|     case META_TILE_NONE: | ||||
|       window->edge_constraints[0] = META_EDGE_CONSTRAINT_NONE; | ||||
|       window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; | ||||
|       window->edge_constraints[2] = META_EDGE_CONSTRAINT_NONE; | ||||
|       window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; | ||||
|       break; | ||||
|  | ||||
|     case META_TILE_MAXIMIZED: | ||||
|       window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       break; | ||||
|  | ||||
|     case META_TILE_LEFT: | ||||
|       window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|  | ||||
|       if (window->tile_match) | ||||
|         window->edge_constraints[1] = META_EDGE_CONSTRAINT_WINDOW; | ||||
|       else | ||||
|         window->edge_constraints[1] = META_EDGE_CONSTRAINT_NONE; | ||||
|  | ||||
|       window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       break; | ||||
|  | ||||
|     case META_TILE_RIGHT: | ||||
|       window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|  | ||||
|       if (window->tile_match) | ||||
|         window->edge_constraints[3] = META_EDGE_CONSTRAINT_WINDOW; | ||||
|       else | ||||
|         window->edge_constraints[3] = META_EDGE_CONSTRAINT_NONE; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   /* h/vmaximize also modify the edge constraints */ | ||||
|   if (window->maximized_vertically) | ||||
|     { | ||||
|       window->edge_constraints[0] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[2] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|     } | ||||
|  | ||||
|   if (window->maximized_horizontally) | ||||
|     { | ||||
|       window->edge_constraints[1] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|       window->edge_constraints[3] = META_EDGE_CONSTRAINT_MONITOR; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_tile (MetaWindow *window) | ||||
| meta_window_tile (MetaWindow   *window, | ||||
|                   MetaTileMode  tile_mode) | ||||
| { | ||||
|   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 */ | ||||
|   if (window->tile_mode == META_TILE_NONE) | ||||
|     return; | ||||
| @@ -2986,6 +3104,9 @@ meta_window_tile (MetaWindow *window) | ||||
|   meta_window_maximize_internal (window, directions, NULL); | ||||
|   meta_screen_update_tile_preview (window->screen, FALSE); | ||||
|  | ||||
|   /* Setup the edge constraints */ | ||||
|   update_edge_constraints (window); | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &old_frame_rect); | ||||
|   meta_window_get_buffer_rect (window, &old_buffer_rect); | ||||
|  | ||||
| @@ -3004,6 +3125,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) | ||||
| { | ||||
| @@ -3102,6 +3233,9 @@ meta_window_unmaximize (MetaWindow        *window, | ||||
|       meta_window_get_frame_rect (window, &old_frame_rect); | ||||
|       meta_window_get_buffer_rect (window, &old_buffer_rect); | ||||
|  | ||||
|       if (unmaximize_vertically) | ||||
|         window->tile_mode = META_TILE_NONE; | ||||
|  | ||||
|       meta_topic (META_DEBUG_WINDOW_OPS, | ||||
|                   "Unmaximizing %s%s\n", | ||||
|                   window->desc, | ||||
| @@ -3114,6 +3248,9 @@ meta_window_unmaximize (MetaWindow        *window, | ||||
|       window->maximized_vertically = | ||||
|         window->maximized_vertically   && !unmaximize_vertically; | ||||
|  | ||||
|       /* Update the edge constraints */ | ||||
|       update_edge_constraints (window); | ||||
|  | ||||
|       /* recalc_features() will eventually clear the cached frame | ||||
|        * extents, but we need the correct frame extents in the code below, | ||||
|        * so invalidate the old frame extents manually up front. | ||||
| @@ -3977,6 +4114,9 @@ meta_window_move_to_monitor (MetaWindow  *window, | ||||
| { | ||||
|   MetaRectangle old_area, new_area; | ||||
|  | ||||
|   if (window->tile_mode != META_TILE_NONE) | ||||
|     window->tile_monitor_number = monitor; | ||||
|  | ||||
|   meta_window_get_work_area_for_monitor (window, | ||||
|                                          window->monitor->number, | ||||
|                                          &old_area); | ||||
| @@ -3998,15 +4138,40 @@ meta_window_move_to_monitor (MetaWindow  *window, | ||||
|       meta_window_move_between_rects (window, &old_area, &new_area); | ||||
|     } | ||||
|  | ||||
|   if (window->tile_mode != META_TILE_NONE) | ||||
|     window->tile_monitor_number = monitor; | ||||
|  | ||||
|   window->preferred_output_winsys_id = window->monitor->winsys_id; | ||||
|  | ||||
|   if (window->fullscreen || window->override_redirect) | ||||
|     meta_screen_queue_check_fullscreen (window->screen); | ||||
| } | ||||
|  | ||||
| static void | ||||
| adjust_size_for_tile_match (MetaWindow *window, | ||||
|                             int        *new_w, | ||||
|                             int        *new_h) | ||||
| { | ||||
|   MetaRectangle work_area, rect; | ||||
|   MetaWindow *tile_match = window->tile_match; | ||||
|  | ||||
|   if (!META_WINDOW_TILED_SIDE_BY_SIDE (window) || !tile_match) | ||||
|     return; | ||||
|  | ||||
|   meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area); | ||||
|  | ||||
|   /* Make sure the resize does not break minimum sizes */ | ||||
|   rect = work_area; | ||||
|   rect.width = *new_w; | ||||
|  | ||||
|   meta_window_frame_rect_to_client_rect (window, &rect, &rect); | ||||
|   *new_w += MAX(0, window->size_hints.min_width - rect.width); | ||||
|  | ||||
|   /* Make sure we're not resizing the tile match below its min width */ | ||||
|   rect = work_area; | ||||
|   rect.width = work_area.width - *new_w; | ||||
|  | ||||
|   meta_window_frame_rect_to_client_rect (tile_match, &rect, &rect); | ||||
|   *new_w -= MAX(0, tile_match->size_hints.min_width - rect.width); | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_resize_frame_with_gravity (MetaWindow *window, | ||||
|                                        gboolean     user_op, | ||||
| @@ -4020,6 +4185,16 @@ meta_window_resize_frame_with_gravity (MetaWindow *window, | ||||
|   rect.width = w; | ||||
|   rect.height = h; | ||||
|  | ||||
|   if (user_op) | ||||
|     { | ||||
|       /* When resizing in-tandem with a tile match, we need to respect | ||||
|        * its minimum width | ||||
|        */ | ||||
|       if (window->display->grab_window == window) | ||||
|         adjust_size_for_tile_match (window, &w, &h); | ||||
|       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); | ||||
| } | ||||
| @@ -4764,7 +4939,13 @@ meta_window_raise (MetaWindow  *window) | ||||
|    * the child windows appropriately. | ||||
|    */ | ||||
|   if (window->screen->stack == ancestor->screen->stack) | ||||
|     meta_stack_raise (window->screen->stack, ancestor); | ||||
|     { | ||||
|       /* If the window has a tile sibling, raise it before raising the window itself */ | ||||
|       if (window->tile_match) | ||||
|         meta_stack_raise (window->tile_match->screen->stack, window->tile_match); | ||||
|  | ||||
|       meta_stack_raise (window->screen->stack, ancestor); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       meta_warning ( | ||||
| @@ -4796,6 +4977,10 @@ meta_window_lower (MetaWindow  *window) | ||||
|   meta_topic (META_DEBUG_WINDOW_OPS, | ||||
|               "Lowering window %s\n", window->desc); | ||||
|  | ||||
|   /* If the window has a tile sibling, lower it before loweting the window itself */ | ||||
|   if (window->tile_match) | ||||
|     meta_stack_lower (window->tile_match->screen->stack, window->tile_match); | ||||
|  | ||||
|   meta_stack_lower (window->screen->stack, window); | ||||
| } | ||||
|  | ||||
| @@ -5713,6 +5898,7 @@ update_move_maybe_tile (MetaWindow *window, | ||||
|   MetaMonitorManager *monitor_manager = | ||||
|     meta_backend_get_monitor_manager (backend); | ||||
|   MetaLogicalMonitor *logical_monitor; | ||||
|   MetaScreen *screen = window->screen; | ||||
|   MetaRectangle work_area; | ||||
|  | ||||
|   /* For side-by-side tiling we are interested in the inside vertical | ||||
| @@ -5742,18 +5928,18 @@ update_move_maybe_tile (MetaWindow *window, | ||||
|    */ | ||||
|   if (meta_window_can_tile_side_by_side (window) && | ||||
|       x >= logical_monitor->rect.x && x < (work_area.x + shake_threshold)) | ||||
|     window->tile_mode = META_TILE_LEFT; | ||||
|     screen->preview_tile_mode = META_TILE_LEFT; | ||||
|   else if (meta_window_can_tile_side_by_side (window) && | ||||
|            x >= work_area.x + work_area.width - shake_threshold && | ||||
|            x < (logical_monitor->rect.x + logical_monitor->rect.width)) | ||||
|     window->tile_mode = META_TILE_RIGHT; | ||||
|     screen->preview_tile_mode = META_TILE_RIGHT; | ||||
|   else if (meta_window_can_tile_maximized (window) && | ||||
|            y >= logical_monitor->rect.y && y <= work_area.y) | ||||
|     window->tile_mode = META_TILE_MAXIMIZED; | ||||
|     screen->preview_tile_mode = META_TILE_MAXIMIZED; | ||||
|   else | ||||
|     window->tile_mode = META_TILE_NONE; | ||||
|     screen->preview_tile_mode = META_TILE_NONE; | ||||
|  | ||||
|   if (window->tile_mode != META_TILE_NONE) | ||||
|   if (screen->preview_tile_mode != META_TILE_NONE) | ||||
|     window->tile_monitor_number = logical_monitor->number; | ||||
| } | ||||
|  | ||||
| @@ -5768,6 +5954,7 @@ update_move (MetaWindow  *window, | ||||
|   MetaRectangle old; | ||||
|   int shake_threshold; | ||||
|   MetaDisplay *display = window->display; | ||||
|   MetaScreen *screen = window->screen; | ||||
|  | ||||
|   display->grab_latest_motion_x = x; | ||||
|   display->grab_latest_motion_y = y; | ||||
| @@ -5805,7 +5992,7 @@ update_move (MetaWindow  *window, | ||||
|     { | ||||
|       /* We don't want to tile while snapping. Also, clear any previous tile | ||||
|          request. */ | ||||
|       window->tile_mode = META_TILE_NONE; | ||||
|       screen->preview_tile_mode = META_TILE_NONE; | ||||
|       window->tile_monitor_number = -1; | ||||
|     } | ||||
|   else if (meta_prefs_get_edge_tiling () && | ||||
| @@ -5921,8 +6108,8 @@ update_move (MetaWindow  *window, | ||||
|    * trigger it unwittingly, e.g. when shaking loose the window or moving | ||||
|    * it to another monitor. | ||||
|    */ | ||||
|   meta_screen_update_tile_preview (window->screen, | ||||
|                                    window->tile_mode != META_TILE_NONE); | ||||
|   meta_screen_update_tile_preview (screen, | ||||
|                                    screen->preview_tile_mode != META_TILE_NONE); | ||||
|  | ||||
|   meta_window_get_frame_rect (window, &old); | ||||
|  | ||||
| @@ -6089,20 +6276,21 @@ update_resize (MetaWindow *window, | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_tile_mode (MetaWindow *window) | ||||
| maybe_maximize_tiled_window (MetaWindow *window) | ||||
| { | ||||
|   switch (window->tile_mode) | ||||
|     { | ||||
|       case META_TILE_LEFT: | ||||
|       case META_TILE_RIGHT: | ||||
|           if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|               window->tile_mode = META_TILE_NONE; | ||||
|           break; | ||||
|       case META_TILE_MAXIMIZED: | ||||
|           if (!META_WINDOW_MAXIMIZED (window)) | ||||
|               window->tile_mode = META_TILE_NONE; | ||||
|           break; | ||||
|     } | ||||
|   MetaRectangle work_area; | ||||
|   gint shake_threshold; | ||||
|  | ||||
|   if (!META_WINDOW_TILED_SIDE_BY_SIDE (window)) | ||||
|     return; | ||||
|  | ||||
|   shake_threshold = meta_prefs_get_drag_threshold (); | ||||
|  | ||||
|   meta_window_get_work_area_for_monitor (window, | ||||
|                                          window->tile_monitor_number, | ||||
|                                          &work_area); | ||||
|   if (window->rect.width >= work_area.width - shake_threshold) | ||||
|     meta_window_maximize (window, META_MAXIMIZE_BOTH); | ||||
| } | ||||
|  | ||||
| void | ||||
| @@ -6135,8 +6323,8 @@ end_grab_op (MetaWindow *window, | ||||
|     { | ||||
|       if (meta_grab_op_is_moving (window->display->grab_op)) | ||||
|         { | ||||
|           if (window->tile_mode != META_TILE_NONE) | ||||
|             meta_window_tile (window); | ||||
|           if (window->screen->preview_tile_mode != META_TILE_NONE) | ||||
|             meta_window_tile (window, window->screen->preview_tile_mode); | ||||
|           else | ||||
|             update_move (window, | ||||
|                          modifiers & CLUTTER_SHIFT_MASK, | ||||
| @@ -6145,20 +6333,13 @@ end_grab_op (MetaWindow *window, | ||||
|       else if (meta_grab_op_is_resizing (window->display->grab_op)) | ||||
|         { | ||||
|           update_resize (window, | ||||
|                          modifiers & CLUTTER_SHIFT_MASK, | ||||
|                          modifiers & CLUTTER_SHIFT_MASK || window->tile_match != NULL, | ||||
|                          x, y, | ||||
|                          TRUE); | ||||
|  | ||||
|           /* If a tiled window has been dragged free with a | ||||
|            * mouse resize without snapping back to the tiled | ||||
|            * state, it will end up with an inconsistent tile | ||||
|            * mode on mouse release; cleaning the mode earlier | ||||
|            * would break the ability to snap back to the tiled | ||||
|            * state, so we wait until mouse release. | ||||
|            */ | ||||
|           update_tile_mode (window); | ||||
|           maybe_maximize_tiled_window (window); | ||||
|         } | ||||
|     } | ||||
|   window->screen->preview_tile_mode = META_TILE_NONE; | ||||
|   meta_display_end_grab_op (window->display, clutter_event_get_time (event)); | ||||
| } | ||||
|  | ||||
| @@ -6229,7 +6410,7 @@ meta_window_handle_mouse_grab_op_event  (MetaWindow         *window, | ||||
|       else if (meta_grab_op_is_resizing (window->display->grab_op)) | ||||
|         { | ||||
|           update_resize (window, | ||||
|                          modifier_state & CLUTTER_SHIFT_MASK, | ||||
|                          modifier_state & CLUTTER_SHIFT_MASK || window->tile_match != NULL, | ||||
|                          x, y, | ||||
|                          FALSE); | ||||
|         } | ||||
| @@ -6362,23 +6543,26 @@ meta_window_get_current_tile_monitor_number (MetaWindow *window) | ||||
| } | ||||
|  | ||||
| void | ||||
| meta_window_get_current_tile_area (MetaWindow    *window, | ||||
|                                    MetaRectangle *tile_area) | ||||
| 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 (window->tile_mode != META_TILE_NONE); | ||||
|   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 (window->tile_mode == META_TILE_LEFT  || | ||||
|       window->tile_mode == META_TILE_RIGHT) | ||||
|     tile_area->width /= 2; | ||||
|   *tile_area = work_area; | ||||
|   tile_area->width = round (tile_area->width * fraction); | ||||
|  | ||||
|   if (window->tile_mode == META_TILE_RIGHT) | ||||
|     tile_area->x += tile_area->width; | ||||
|   if (tile_mode == META_TILE_RIGHT) | ||||
|     tile_area->x += work_area.width - tile_area->width; | ||||
| } | ||||
|  | ||||
| gboolean | ||||
| @@ -7511,22 +7695,27 @@ meta_window_get_tile_match (MetaWindow *window) | ||||
|  | ||||
| void | ||||
| meta_window_compute_tile_match (MetaWindow *window) | ||||
| { | ||||
|   window->tile_match = meta_window_find_tile_match (window, window->tile_mode); | ||||
| } | ||||
|  | ||||
| static MetaWindow * | ||||
| meta_window_find_tile_match (MetaWindow   *window, | ||||
|                              MetaTileMode  current_mode) | ||||
| { | ||||
|   MetaWindow *match; | ||||
|   MetaStack *stack; | ||||
|   MetaTileMode match_tile_mode = META_TILE_NONE; | ||||
|  | ||||
|   window->tile_match = NULL; | ||||
|  | ||||
|   if (window->shaded || window->minimized) | ||||
|     return; | ||||
|     return NULL; | ||||
|  | ||||
|   if (META_WINDOW_TILED_LEFT (window)) | ||||
|   if (current_mode == META_TILE_LEFT) | ||||
|     match_tile_mode = META_TILE_RIGHT; | ||||
|   else if (META_WINDOW_TILED_RIGHT (window)) | ||||
|   else if (current_mode == META_TILE_RIGHT) | ||||
|     match_tile_mode = META_TILE_LEFT; | ||||
|   else | ||||
|     return; | ||||
|     return NULL; | ||||
|  | ||||
|   stack = window->screen->stack; | ||||
|  | ||||
| @@ -7537,7 +7726,7 @@ meta_window_compute_tile_match (MetaWindow *window) | ||||
|       if (!match->shaded && | ||||
|           !match->minimized && | ||||
|           match->tile_mode == match_tile_mode && | ||||
|           match->monitor == window->monitor && | ||||
|           match->tile_monitor_number == window->tile_monitor_number && | ||||
|           meta_window_get_workspace (match) == meta_window_get_workspace (window)) | ||||
|         break; | ||||
|     } | ||||
| @@ -7560,6 +7749,23 @@ meta_window_compute_tile_match (MetaWindow *window) | ||||
|  | ||||
|       meta_window_get_frame_rect (bottommost, &bottommost_rect); | ||||
|       meta_window_get_frame_rect (topmost, &topmost_rect); | ||||
|  | ||||
|       /* | ||||
|        * If we are looking for a tile match while actually being tiled, | ||||
|        * rather than a match for a potential tile mode, then discard | ||||
|        * windows with too much gap or overlap | ||||
|        */ | ||||
|       if (window->tile_mode == current_mode && | ||||
|           !(meta_grab_op_is_resizing (window->display->grab_op) && | ||||
|             window->display->grab_window == window && | ||||
|             window->tile_match != NULL)) | ||||
|         { | ||||
|           int threshold = meta_prefs_get_drag_threshold (); | ||||
|           if (ABS (topmost_rect.x - bottommost_rect.x - bottommost_rect.width) > threshold && | ||||
|               ABS (bottommost_rect.x - topmost_rect.x - topmost_rect.width) > threshold) | ||||
|             return NULL; | ||||
|         } | ||||
|  | ||||
|       /* | ||||
|        * If there's a window stacked in between which is partially visible | ||||
|        * behind the topmost tile we don't consider the tiles to match. | ||||
| @@ -7577,11 +7783,11 @@ meta_window_compute_tile_match (MetaWindow *window) | ||||
|  | ||||
|           if (meta_rectangle_overlap (&above_rect, &bottommost_rect) && | ||||
|               meta_rectangle_overlap (&above_rect, &topmost_rect)) | ||||
|             return; | ||||
|             return NULL; | ||||
|         } | ||||
|  | ||||
|       window->tile_match = match; | ||||
|     } | ||||
|  | ||||
|   return match; | ||||
| } | ||||
|  | ||||
| void | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -148,31 +148,124 @@ gtk_surface_surface_destroyed (MetaWaylandGtkSurface *gtk_surface) | ||||
| } | ||||
|  | ||||
| static void | ||||
| fill_states (struct wl_array *states, | ||||
|              MetaWindow      *window) | ||||
| fill_edge_states (struct wl_array *states, | ||||
|                   MetaWindow      *window) | ||||
| { | ||||
|   uint32_t *s; | ||||
|  | ||||
|   if (window->tile_mode == META_TILE_LEFT || | ||||
|       window->tile_mode == META_TILE_RIGHT) | ||||
|   /* Top */ | ||||
|   if (window->edge_constraints[0] != META_EDGE_CONSTRAINT_MONITOR) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_TOP; | ||||
|     } | ||||
|  | ||||
|   /* Right */ | ||||
|   if (window->edge_constraints[1] != META_EDGE_CONSTRAINT_MONITOR) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_RIGHT; | ||||
|     } | ||||
|  | ||||
|   /* Bottom */ | ||||
|   if (window->edge_constraints[2] != META_EDGE_CONSTRAINT_MONITOR) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_BOTTOM; | ||||
|     } | ||||
|  | ||||
|   /* Left */ | ||||
|   if (window->edge_constraints[3] != META_EDGE_CONSTRAINT_MONITOR) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_EDGE_CONSTRAINT_RESIZABLE_LEFT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| send_configure_edges (MetaWaylandGtkSurface *gtk_surface, | ||||
|                       MetaWindow            *window) | ||||
| { | ||||
|   struct wl_array edge_states; | ||||
|  | ||||
|   wl_array_init (&edge_states); | ||||
|   fill_edge_states (&edge_states, window); | ||||
|  | ||||
|   gtk_surface1_send_configure_edges (gtk_surface->resource, &edge_states); | ||||
|  | ||||
|   wl_array_release (&edge_states); | ||||
| } | ||||
|  | ||||
| static void | ||||
| fill_states (struct wl_array    *states, | ||||
|              MetaWindow         *window, | ||||
|              struct wl_resource *resource) | ||||
| { | ||||
|   uint32_t *s; | ||||
|   guint version; | ||||
|  | ||||
|   version = wl_resource_get_version (resource); | ||||
|  | ||||
|   if (version < GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION && | ||||
|       (window->tile_mode == META_TILE_LEFT || | ||||
|        window->tile_mode == META_TILE_RIGHT)) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_STATE_TILED; | ||||
|     } | ||||
|  | ||||
|   if (version >= GTK_SURFACE1_STATE_TILED_TOP_SINCE_VERSION && | ||||
|       window->edge_constraints[0] != META_EDGE_CONSTRAINT_NONE) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_STATE_TILED_TOP; | ||||
|     } | ||||
|  | ||||
|   if (version >= GTK_SURFACE1_STATE_TILED_RIGHT_SINCE_VERSION && | ||||
|       window->edge_constraints[1] != META_EDGE_CONSTRAINT_NONE) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_STATE_TILED_RIGHT; | ||||
|     } | ||||
|  | ||||
|   if (version >= GTK_SURFACE1_STATE_TILED_BOTTOM_SINCE_VERSION && | ||||
|       window->edge_constraints[2] != META_EDGE_CONSTRAINT_NONE) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_STATE_TILED_BOTTOM; | ||||
|     } | ||||
|  | ||||
|   if (version >= GTK_SURFACE1_STATE_TILED_LEFT_SINCE_VERSION && | ||||
|       window->edge_constraints[3] != META_EDGE_CONSTRAINT_NONE) | ||||
|     { | ||||
|       s = wl_array_add (states, sizeof *s); | ||||
|       *s = GTK_SURFACE1_STATE_TILED_LEFT; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| send_configure (MetaWaylandGtkSurface *gtk_surface, | ||||
|                 MetaWindow            *window) | ||||
| { | ||||
|   struct wl_array states; | ||||
|  | ||||
|   wl_array_init (&states); | ||||
|   fill_states (&states, window, gtk_surface->resource); | ||||
|  | ||||
|   gtk_surface1_send_configure (gtk_surface->resource, &states); | ||||
|  | ||||
|   wl_array_release (&states); | ||||
| } | ||||
|  | ||||
| static void | ||||
| on_configure (MetaWaylandSurface    *surface, | ||||
|               MetaWaylandGtkSurface *gtk_surface) | ||||
| { | ||||
|   struct wl_array states; | ||||
|   send_configure (gtk_surface, surface->window); | ||||
|  | ||||
|   wl_array_init (&states); | ||||
|   fill_states (&states, surface->window); | ||||
|  | ||||
|   gtk_surface1_send_configure (gtk_surface->resource, &states); | ||||
|  | ||||
|   wl_array_release (&states); | ||||
|   if (wl_resource_get_version (gtk_surface->resource) >= GTK_SURFACE1_CONFIGURE_EDGES_SINCE_VERSION) | ||||
|     send_configure_edges (gtk_surface, surface->window); | ||||
| } | ||||
|  | ||||
| static void | ||||
|   | ||||
| @@ -42,7 +42,7 @@ | ||||
| #define META_WL_SEAT_VERSION                5 | ||||
| #define META_WL_OUTPUT_VERSION              2 | ||||
| #define META_XSERVER_VERSION                1 | ||||
| #define META_GTK_SHELL1_VERSION             1 | ||||
| #define META_GTK_SHELL1_VERSION             2 | ||||
| #define META_WL_SUBCOMPOSITOR_VERSION       1 | ||||
| #define META_ZWP_POINTER_GESTURES_V1_VERSION    1 | ||||
| #define META_ZXDG_EXPORTER_V1_VERSION       1 | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <protocol name="gtk"> | ||||
|  | ||||
|   <interface name="gtk_shell1" version="1"> | ||||
|   <interface name="gtk_shell1" version="2"> | ||||
|     <description summary="gtk specific extensions"> | ||||
|       gtk_shell is a protocol extension providing additional features for | ||||
|       clients implementing it. | ||||
| @@ -30,7 +30,7 @@ | ||||
|     </request> | ||||
|   </interface> | ||||
|  | ||||
|   <interface name="gtk_surface1" version="1"> | ||||
|   <interface name="gtk_surface1" version="2"> | ||||
|     <request name="set_dbus_properties"> | ||||
|       <arg name="application_id" type="string" allow-null="true"/> | ||||
|       <arg name="app_menu_path" type="string" allow-null="true"/> | ||||
| @@ -51,11 +51,27 @@ | ||||
|  | ||||
|     <enum name="state"> | ||||
|       <entry name="tiled" value="1"/> | ||||
|  | ||||
|       <entry name="tiled_top" value="2" since="2" /> | ||||
|       <entry name="tiled_right" value="3" since="2" /> | ||||
|       <entry name="tiled_bottom" value="4" since="2" /> | ||||
|       <entry name="tiled_left" value="5"  since="2" /> | ||||
|     </enum> | ||||
|  | ||||
|     <enum name="edge_constraint" since="2"> | ||||
|       <entry name="resizable_top" value="1"/> | ||||
|       <entry name="resizable_right" value="2"/> | ||||
|       <entry name="resizable_bottom" value="3"/> | ||||
|       <entry name="resizable_left" value="4"/> | ||||
|     </enum> | ||||
|  | ||||
|     <event name="configure"> | ||||
|       <arg name="states" type="array"/> | ||||
|     </event> | ||||
|  | ||||
|     <event name="configure_edges" since="2"> | ||||
|       <arg name="constraints" type="array"/> | ||||
|     </event> | ||||
|   </interface> | ||||
|  | ||||
| </protocol> | ||||
|   | ||||
| @@ -63,6 +63,7 @@ item(_GTK_APP_MENU_OBJECT_PATH) | ||||
| item(_GTK_MENUBAR_OBJECT_PATH) | ||||
| item(_GTK_FRAME_EXTENTS) | ||||
| item(_GTK_SHOW_WINDOW_MENU) | ||||
| item(_GTK_EDGE_CONSTRAINTS) | ||||
| item(_GNOME_WM_KEYBINDINGS) | ||||
| item(_GNOME_PANEL_ACTION) | ||||
| item(_GNOME_PANEL_ACTION_MAIN_MENU) | ||||
|   | ||||
| @@ -902,6 +902,31 @@ update_net_frame_extents (MetaWindow *window) | ||||
|   meta_error_trap_pop (window->display); | ||||
| } | ||||
|  | ||||
| static void | ||||
| update_gtk_edge_constraints (MetaWindow *window) | ||||
| { | ||||
|   MetaEdgeConstraint *constraints = window->edge_constraints; | ||||
|   unsigned long data[1]; | ||||
|  | ||||
|   /* Edge constraints */ | ||||
|   data[0] = (constraints[0] != META_EDGE_CONSTRAINT_NONE ? 1 : 0)    << 0 | | ||||
|             (constraints[0] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 1 | | ||||
|             (constraints[1] != META_EDGE_CONSTRAINT_NONE ? 1 : 0)    << 2 | | ||||
|             (constraints[1] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 3 | | ||||
|             (constraints[2] != META_EDGE_CONSTRAINT_NONE ? 1 : 0)    << 4 | | ||||
|             (constraints[2] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 5 | | ||||
|             (constraints[3] != META_EDGE_CONSTRAINT_NONE ? 1 : 0)    << 6 | | ||||
|             (constraints[3] != META_EDGE_CONSTRAINT_MONITOR ? 1 : 0) << 7; | ||||
|  | ||||
|   meta_verbose ("Setting _GTK_EDGE_CONSTRAINTS to %lu\n", data[0]); | ||||
|  | ||||
|   XChangeProperty (window->display->xdisplay, | ||||
|                    window->xwindow, | ||||
|                    window->display->atom__GTK_EDGE_CONSTRAINTS, | ||||
|                    XA_CARDINAL, 32, PropModeReplace, | ||||
|                    (guchar*) data, 1); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| sync_request_timeout (gpointer data) | ||||
| { | ||||
| @@ -1259,6 +1284,8 @@ meta_window_x11_move_resize_internal (MetaWindow                *window, | ||||
|     *result |= META_MOVE_RESIZE_RESULT_MOVED; | ||||
|   if (need_resize_client || need_resize_frame) | ||||
|     *result |= META_MOVE_RESIZE_RESULT_RESIZED; | ||||
|  | ||||
|   update_gtk_edge_constraints (window); | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| @@ -1670,6 +1697,9 @@ meta_window_x11_set_net_wm_state (MetaWindow *window) | ||||
|           meta_error_trap_pop (window->display); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   /* Edge constraints */ | ||||
|   update_gtk_edge_constraints (window); | ||||
| } | ||||
|  | ||||
| static cairo_region_t * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user