AtlatestRepositorysigil-wm

sigil-wm / tree / src / cscene-move.h

1/* SPDX-License-Identifier: BSD-3-Clause
2 * Pointer-following is a mechanism over an explicit manager-supplied resource
3 * set. It does not choose floating membership, decoration ownership or order. */
4static void scene_move_finish_reason(struct server *s,int reason) {
5 struct scene_move *move=&s->scene_move;
6 if(!move->active) return;
7 move->active=false;
8 EVENT(38,move->window,move->dx,move->dy,move->token,reason);
9}
10static void scene_move_finish(struct server *s) { scene_move_finish_reason(s,1); }
11static void scene_move_button(struct server *s,const struct input *input) {
12 if(input->kind==31 && !input->state && input->code==s->scene_move.button &&
13 input->device==s->scene_move.device) scene_move_finish_reason(s,0);
15static void scene_move_position(struct server *s,int64_t resource,
16 struct wlr_scene_node *node,int x,int y) {
17 struct scene_move *move=&s->scene_move;
18 if(move->retained) {
19 for(unsigned i=0;i<move->count;i++) {
20 if(move->items[i].id!=resource) continue;
21 x=move->items[i].x+move->dx; y=move->items[i].y+move->dy;
22 break;
23 }
24 }
25 wlr_scene_node_set_position(node,x,y);
27static void scene_move_update(struct server *s) {
28 struct scene_move *move=&s->scene_move;
29 move->dx=(int)round(s->cursor->x-move->pointer_x);
30 move->dy=(int)round(s->cursor->y-move->pointer_y);
31 for(unsigned i=0;i<move->count;i++) {
32 struct wlr_scene_node *node=scene_resource(s,move->items[i].id);
33 if(node) scene_move_position(s,move->items[i].id,node,0,0);
34 }
35 struct view *view=find_view(s,move->window);
36 if(view && view->x11)
37 wlr_xwayland_surface_configure(view->x11,view->tree->node.x,
38 view->tree->node.y,view->width,view->height);
40static bool scene_move_motion(struct server *s,uint32_t time,double x,double y,
41 uint64_t completion,int origin) {
42 struct scene_move *move=&s->scene_move;
43 if(!move->active) return false;
44 struct view *view=find_view(s,move->window);
45 if(s->lock_state || !view || !visible(view)) {
46 scene_move_finish(s); return false;
47 }
48 uint64_t token=++s->next_token;
49 latency_trace(0,token,32,0);
50 s->motion_delivered_token=token;
51 constrained_warp(s,x,y);
52 s->motion_x=s->cursor->x; s->motion_y=s->cursor->y;
53 scene_move_update(s);
54 trace_damage(s,token,0);
55 route_motion(s,time,true);
56 if(completion) EVENT(35,completion,1,origin,token);
57 return true;
59static bool scene_move_start(struct server *s,uint64_t token,const int64_t *w,size_t n) {
60 if(n<6 || w[0]<=0 || w[1]<272 || w[1]>=288 ||
61 w[2]<-32768000 || w[2]>32768000 || w[3]<-32768000 || w[3]>32768000 ||
62 w[4]<1 || w[4]>256 || n!=5+(size_t)w[4]) return false;
63 /* Validate copied shape before checking state that can retire in transit. */
64 bool owner=false;
65 for(unsigned i=0;i<(unsigned)w[4];i++) {
66 int64_t id=w[5+i];
67 if(!id || id==INT64_MIN) return false;
68 for(unsigned j=0;j<i;j++) if(w[5+j]==id) return false;
69 if(id==w[0]) owner=true;
70 }
71 if(!owner) return false;
72 struct view *view=find_view(s,w[0]);
73 bool held=false;
74 uint64_t device=0;
75 for(unsigned i=0;i<QUEUE_SIZE;i++) {
76 if((s->buttons[i].held && s->buttons[i].code==w[1]) ||
77 (s->intercepted_buttons[i].held && s->intercepted_buttons[i].code==w[1])) {
78 held=true;
79 device=s->intercepted_buttons[i].held && s->intercepted_buttons[i].code==w[1] ?
80 s->intercepted_buttons[i].device : s->buttons[i].device;
81 }
82 }
83 /* A quick release, unmap, lock or decoration retirement can precede this
84 * asynchronous admission. Complete the manager token without rejecting its
85 * command or resurrecting a gesture that has already ended. */
86 if(s->lock_state || !held || !view || !visible(view) || view->layer) {
87 EVENT(38,w[0],0,0,token,1); return true;
88 }
89 struct scene_move next={.retained=true,.active=true,.token=token,
90 .window=w[0],.device=device,.button=w[1],.pointer_x=w[2]/1000.0,.pointer_y=w[3]/1000.0,.count=w[4]};
91 for(unsigned i=0;i<next.count;i++) {
92 int64_t id=w[5+i];
93 struct wlr_scene_node *node=scene_resource(s,id);
94 if(!node || node->parent!=s->normal) {
95 EVENT(38,w[0],0,0,token,1); return true;
96 }
97 next.items[i]=(struct scene_move_item){id,node->x,node->y};
98 }
99 scene_move_finish(s);
100 s->scene_move=next;
101 scene_move_update(s);
102 return true;
104/* Delayed plans/uploads cannot undo newer pointer motion. Keep the final
105 * position through release until the manager acknowledges it in a full plan. */
106static void scene_move_plan(struct server *s,const int64_t *w) {
107 struct scene_move *move=&s->scene_move;
108 if(!move->retained) return;
109 struct view *view=find_view(s,move->window);
110 if(!view || !view->mapped) { scene_move_finish(s); move->retained=false; return; }
111 for(int i=0;i<w[1];i++) {
112 const int64_t *p=w+4+10*i;
113 if(p[0]!=(int64_t)move->window) continue;
114 if(!p[5] || p[7] || p[8]) {
115 scene_move_finish(s); move->retained=false; return;
116 }
117 if(!move->active) {
118 struct wlr_scene_node *node=scene_resource(s,move->window);
119 if(node && p[1]==node->x && p[2]==node->y) move->retained=false;
120 }
121 break;
122 }