Commitb5dc0273Recorded29 Oct 2026Repositorysigil-wm

Cancel pointer following for explicit placement transitions

Changed
 README.md          | 10 ++++++++++
 scripts/check      |  3 ++-
 src/c/scene-move.h |  7 +++++--
 test/scene-move.c  |  4 ++++
 4 files changed, 21 insertions(+), 3 deletions(-)
Diff
README.mdmodified
@@ -4,6 +4,16 @@
4
5
A toolkit for writing Wayland window managers in Sigil, built on wlroots.
6
The native thread owns Wayland objects, input transport and scene presentation.
+7
+8
Interactive scene translation uses `start-scene-move!` with a window, held
+9
button, pointer anchor and an explicit set of window/pixel resources (at most
+10
256). The native owner follows pointer motion without a manager round trip or
+11
restacking. `scene-move-ended` reports `delta-x:`, `delta-y:`, `move-token:`
+12
and `reason:` (0 release, 1 cancellation). The manager reconciles its geometry
+13
in the next full plan; stale plans cannot rewind the move. Explicit fullscreen,
+14
tiled or hidden placements cancel translation. `stop-scene-move!`, lock, unmap
+15
and initiating-device removal also stop it.
+16
17
Sigil chooses placement, visibility, stacking, focus and input handling.
18
19
The library namespaces are `(sigil wm host)`, `(sigil wm model)`,
scripts/checkmodified
@@ -4,7 +4,8 @@ cd "$(dirname "$0")/.."
4
if [[ ${1:-} != --inside ]]; then
5
exec guix time-machine -C channels.scm -- shell -m draw-manifest.scm -- bash scripts/check --inside
6
fi
−7
make -j2
+7
make -j2 all build/scene-move-test
+8
build/scene-move-test
9
bash scripts/test-environment-exec
10
bash scripts/run-sigil -L src -L examples -L .deps eval -f test/imports.sgl
11
src/c/scene-move.hmodified
@@ -95,11 +95,14 @@ static bool scene_move_start(struct server *s,uint64_t token,const int64_t *w,si
95
static void scene_move_plan(struct server *s,const int64_t *w) {
96
struct scene_move *move=&s->scene_move;
97
if(!move->retained) return;
−98
if(!find_view(s,move->window)) { scene_move_finish(s); move->retained=false; return; }
+98
struct view *view=find_view(s,move->window);
+99
if(!view || !view->mapped) { scene_move_finish(s); move->retained=false; return; }
100
for(int i=0;i<w[1];i++) {
101
const int64_t *p=w+4+10*i;
102
if(p[0]!=(int64_t)move->window) continue;
−102
if(!p[5]) scene_move_finish(s);
+103
if(!p[5] || p[7] || p[8]) {
+104
scene_move_finish(s); move->retained=false; return;
+105
}
106
if(!move->active) {
107
struct wlr_scene_node *node=scene_resource(s,move->window);
108
if(node && p[1]==node->x && p[2]==node->y) move->retained=false;
test/scene-move.cmodified
@@ -45,6 +45,10 @@ int main(void) {
45
int64_t missing_owner[]={1,272,40000,40000,1,-2};
46
assert(!scene_move_start(&s,12,missing_owner,6));
47
payload[2]=INT64_MAX; assert(!scene_move_start(&s,12,payload,7)); payload[2]=80000; payload[3]=60000;
+48
assert(scene_move_start(&s,12,payload,7));
+49
stale[5]=0; stale[6]=0; stale[11]=1;
+50
scene_move_plan(&s,stale); assert(!s.scene_move.active && !s.scene_move.retained);
+51
scene_move_position(&s,1,&view.tree->node,0,0); assert(view.tree->node.x==0);
52
assert(scene_move_start(&s,13,payload,7));
53
s.lock_state=1; assert(!scene_move_motion(&s,0,90,60,0,0)); assert(!s.scene_move.active);
54
s.lock_state=0; assert(scene_move_start(&s,14,payload,7));