@@ -127,33 +127,83 @@ Cursor::Cursor(Seat *seat) : server(seat->server), seat(seat->wlr_seat) {
127127 wlr_scene_node *node =
128128 wlr_scene_node_at (&server->scene ->tree .node , cursor->cursor ->x ,
129129 cursor->cursor ->y , &sx, &sy);
130- while (node && node->type == WLR_SCENE_NODE_RECT) {
130+
131+ // hit detect decoration of toplevel
132+ if (!toplevel && node && node->type == WLR_SCENE_NODE_RECT) {
131133 wlr_scene_rect *rect = wl_container_of (node, rect, node);
132- if (! rect)
133- break ;
134- Decoration *decoration =
135- static_cast <Decoration *>(rect-> node . parent -> node . data );
136- if (! decoration)
137- break ;
138- toplevel = decoration-> toplevel ;
134+ if (rect && rect-> node . parent && rect-> node . parent -> node . data ) {
135+ Decoration *decoration =
136+ static_cast < Decoration *>(rect-> node . parent -> node . data );
137+ if (decoration && decoration-> toplevel )
138+ toplevel = decoration-> toplevel ;
139+ }
140+ }
139141
140- switch (decoration->get_part_from_node (node)) {
141- case DecorationPart::TITLEBAR:
142- toplevel->begin_interactive (CURSORMODE_MOVE, 0 );
143- break ;
144- case DecorationPart::CLOSE_BUTTON:
145- toplevel->close ();
146- break ;
147- case DecorationPart::MAXIMIZE_BUTTON:
148- toplevel->toggle_maximized ();
149- break ;
150- case DecorationPart::FULLSCREEN_BUTTON:
151- toplevel->toggle_fullscreen ();
152- break ;
153- default :
142+ bool handled_edge_resize = false ;
143+ if (toplevel && !toplevel->fullscreen ()) {
144+ const int RESIZE_BORDER = 10 ;
145+ wlr_box geo = toplevel->geometry ;
146+ double x = cursor->cursor ->x ;
147+ double y = cursor->cursor ->y ;
148+
149+ // include titlebar if applicable
150+ int visual_top = geo.y ;
151+ int visual_height = geo.height ;
152+ if (toplevel->decoration &&
153+ toplevel->decoration_mode == WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE &&
154+ toplevel->decoration ->visible ) {
155+ visual_top -= TITLEBAR_HEIGHT;
156+ visual_height += TITLEBAR_HEIGHT;
157+ }
158+
159+ uint32_t edges = 0 ;
160+ // left/right
161+ if (x >= geo.x - RESIZE_BORDER && x <= geo.x + RESIZE_BORDER)
162+ edges |= WLR_EDGE_LEFT;
163+ else if (x >= geo.x + geo.width - RESIZE_BORDER && x <= geo.x + geo.width + RESIZE_BORDER)
164+ edges |= WLR_EDGE_RIGHT;
165+
166+ // top/bottom
167+ if (y >= visual_top - RESIZE_BORDER && y <= visual_top + RESIZE_BORDER)
168+ edges |= WLR_EDGE_TOP;
169+ else if (y >= visual_top + visual_height - RESIZE_BORDER && y <= visual_top + visual_height + RESIZE_BORDER)
170+ edges |= WLR_EDGE_BOTTOM;
171+
172+ if (edges != 0 ) {
173+ toplevel->begin_interactive (CURSORMODE_RESIZE, edges);
174+ handled_edge_resize = true ;
175+ }
176+ }
177+
178+ if (!handled_edge_resize) {
179+ while (node && node->type == WLR_SCENE_NODE_RECT) {
180+ wlr_scene_rect *rect = wl_container_of (node, rect, node);
181+ if (!rect)
182+ break ;
183+ Decoration *decoration =
184+ static_cast <Decoration *>(rect->node .parent ->node .data );
185+ if (!decoration)
186+ break ;
187+ toplevel = decoration->toplevel ;
188+
189+ switch (decoration->get_part_from_node (node)) {
190+ case DecorationPart::TITLEBAR:
191+ toplevel->begin_interactive (CURSORMODE_MOVE, 0 );
192+ break ;
193+ case DecorationPart::CLOSE_BUTTON:
194+ toplevel->close ();
195+ break ;
196+ case DecorationPart::MAXIMIZE_BUTTON:
197+ toplevel->toggle_maximized ();
198+ break ;
199+ case DecorationPart::FULLSCREEN_BUTTON:
200+ toplevel->toggle_fullscreen ();
201+ break ;
202+ default :
203+ break ;
204+ }
154205 break ;
155206 }
156- break ;
157207 }
158208
159209 // add to pressed buttons
0 commit comments