Share one placement path when a window changes display
6b057b8f0824639850c9b125150c9db3e60d9162
1 parent
7dba09d7
swm.c
+26 -22
| 436 | 436 | struct wl_listener listener; |
|
| 437 | 437 | } static_listener_t; |
|
| 438 | 438 | ||
| 439 | 439 | /* Function declarations. */ |
|
| 440 | 440 | static void apply_bounds(client_t *c, struct wlr_box *bbox); |
|
| 441 | + | static void client_place(client_t *c); |
|
| 441 | 442 | static void apply_rules(client_t *c, workspace_t *defaultws); |
|
| 442 | 443 | static unsigned int client_border_width(client_t *c); |
|
| 443 | 444 | static void arrange(monitor_t *m); |
|
| 444 | 445 | static void arrange_layer( |
|
| 445 | 446 | monitor_t *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive |
| 5010 | 5011 | ||
| 5011 | 5012 | if (mv && sel) |
|
| 5012 | 5013 | focus_client(sel, 1); |
|
| 5013 | 5014 | } |
|
| 5014 | 5015 | ||
| 5016 | + | /* Fit a window to the display it was just moved to. */ |
|
| 5017 | + | void client_place(client_t *c) { |
|
| 5018 | + | /* An initial commit may assign a monitor before map_notify() creates the |
|
| 5019 | + | * client's scene tree. Defer all scene operations until the surface maps. */ |
|
| 5020 | + | if (!c->mon || !client_surface(c)->mapped) |
|
| 5021 | + | return; |
|
| 5022 | + | ||
| 5023 | + | /* Keep the window overlapping its display. */ |
|
| 5024 | + | if (c->is_fullscreen) { |
|
| 5025 | + | client_set_fullscreen(c, 1); |
|
| 5026 | + | wlr_scene_node_reparent(&c->scene->node, layers[LAYER_FULLSCREEN]); |
|
| 5027 | + | resize(c, c->mon->m, 0); |
|
| 5028 | + | } else { |
|
| 5029 | + | resize(c, c->geom, 0); |
|
| 5030 | + | set_floating(c, c->is_floating); |
|
| 5031 | + | } |
|
| 5032 | + | } |
|
| 5033 | + | ||
| 5015 | 5034 | /* Move a window to a display and keep its workspace and scale consistent. */ |
|
| 5016 | 5035 | void set_monitor(client_t *c, monitor_t *m, workspace_t *ws) { |
|
| 5017 | 5036 | monitor_t *oldmon = c->mon; |
|
| 5018 | 5037 | ||
| 5019 | 5038 | if (!ws) |
| 5036 | 5055 | c->prev = c->geom; |
|
| 5037 | 5056 | ||
| 5038 | 5057 | /* Moving this node tells applications which displays they overlap. */ |
|
| 5039 | 5058 | if (oldmon) |
|
| 5040 | 5059 | arrange(oldmon); |
|
| 5041 | - | /* An initial commit may assign a monitor before map_notify() creates the |
|
| 5042 | - | * client's scene tree. Defer all scene operations until the surface maps. */ |
|
| 5043 | - | if (m && client_surface(c)->mapped) { |
|
| 5044 | - | /* Keep the window overlapping its display. */ |
|
| 5045 | - | if (c->is_fullscreen) { |
|
| 5046 | - | client_set_fullscreen(c, 1); |
|
| 5047 | - | wlr_scene_node_reparent(&c->scene->node, layers[LAYER_FULLSCREEN]); |
|
| 5048 | - | resize(c, m->m, 0); |
|
| 5049 | - | } else { |
|
| 5050 | - | resize(c, c->geom, 0); |
|
| 5051 | - | set_floating(c, c->is_floating); |
|
| 5052 | - | } |
|
| 5053 | - | } |
|
| 5060 | + | client_place(c); |
|
| 5054 | 5061 | focus_client(focus_top(selmon), 1); |
|
| 5055 | 5062 | } |
|
| 5056 | 5063 | ||
| 5057 | 5064 | /* Move a window and any related windows to another workspace. */ |
|
| 5058 | 5065 | void set_workspace(client_t *c, workspace_t *ws) { |
| 5070 | 5077 | w->ws = ws; |
|
| 5071 | 5078 | ||
| 5072 | 5079 | if (ws->mon && ws->mon != w->mon) { |
|
| 5073 | 5080 | w->mon = ws->mon; |
|
| 5074 | 5081 | ||
| 5075 | - | if (w->is_fullscreen) { |
|
| 5076 | - | client_set_fullscreen(w, 1); |
|
| 5077 | - | wlr_scene_node_reparent(&w->scene->node, layers[LAYER_FULLSCREEN]); |
|
| 5078 | - | resize(w, w->mon->m, 0); |
|
| 5079 | - | } else { |
|
| 5082 | + | if (!w->is_fullscreen) |
|
| 5080 | 5083 | w->prev = w->geom; |
|
| 5081 | - | resize(w, w->geom, 0); |
|
| 5082 | - | set_floating(w, w->is_floating); |
|
| 5083 | - | } |
|
| 5084 | + | client_place(w); |
|
| 5084 | 5085 | } |
|
| 5085 | 5086 | } |
|
| 5086 | 5087 | if (oldmon) |
|
| 5087 | 5088 | arrange(oldmon); |
|
| 5088 | 5089 |
| 5092 | 5093 | print_status(); |
|
| 5093 | 5094 | } |
|
| 5094 | 5095 | ||
| 5095 | 5096 | /* Show a workspace on a display and synchronize all of its windows. */ |
|
| 5096 | 5097 | void assign_workspace(workspace_t *ws, monitor_t *m) { |
|
| 5097 | - | /* Attach a workspace to a display and update all of its windows. */ |
|
| 5098 | + | /* Attach a workspace to a display and update all of its windows. This |
|
| 5099 | + | * deliberately does less than client_place(): callers arrange the display |
|
| 5100 | + | * afterwards, which settles layers and tiled geometry for the whole |
|
| 5101 | + | * workspace at once. */ |
|
| 5098 | 5102 | client_t *c; |
|
| 5099 | 5103 | ||
| 5100 | 5104 | ws->mon = m; |
|
| 5101 | 5105 | ||
| 5102 | 5106 | if (!m) |