AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause2
* Pointer-following is a mechanism over an explicit manager-supplied resource3
* set. It does not choose floating membership, decoration ownership or order. */4
static 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
}10
static void scene_move_finish(struct server *s) { scene_move_finish_reason(s,1); }11
static 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);14
}15
static 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);26
}27
static 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);39
}40
static 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;58
}59
static 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 this84
* asynchronous admission. Complete the manager token without rejecting its85
* 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;103
}104
/* Delayed plans/uploads cannot undo newer pointer motion. Keep the final105
* position through release until the manager acknowledges it in a full plan. */106
static 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
}123
}