refactor(xwm): log counters on close, drop the test-only Slot lookup and state atoms in present tense
8 files · +58 -57
M docs/dev/headless.md +1 -1
| @@ -66,7 +66,7 @@ WAYLAND_DISPLAY=<name> go run ./examples/testime -preedit nihon -commit 日本 | |||
| 66 | 66 | ||
| 67 | 67 | `make e2e-xwayland` runs the end-to-end test of the built-in window manager (`xwayland = builtin`). It is behind the `xwayland` build tag, so `go test ./...` and `make check` only compile it (`go vet -tags xwayland`). It needs `Xwayland` on `PATH` and a GPU, and skips without Xwayland. | |
| 68 | 68 | ||
| 69 | - | The test starts a headless NeferWL with a real `Xwayland` and runs `internal/app/testdata/x11probe`, a small X11 client (`-class`, `-title`, `-size`, `-sleep`) that paints its window green, prints `mapped WxH` and `focus`, and exits 0 on `WM_DELETE_WINDOW`. It checks: | |
| 69 | + | The test starts a headless NeferWL with a real `Xwayland` on the first free X display (a live session's `:0` stays untouched) and runs `internal/app/testdata/x11probe`, a small X11 client (`-class`, `-title`, `-size`, `-sleep`) that paints its window green, prints `mapped WxH` and `focus`, and exits 0 on `WM_DELETE_WINDOW`. It checks: | |
| 70 | 70 | ||
| 71 | 71 | - the state lists one visible `X11Probe` window with the probe's pid, and the screenshot is mostly green inside its tile; | |
| 72 | 72 | - the probe receives focus; | |
| @@ -66,7 +66,7 @@ WAYLAND_DISPLAY=<name> go run ./examples/testime -preedit nihon -commit 日本 | |||||
| 66 | 66 | ||||
| 67 | `make e2e-xwayland` runs the end-to-end test of the built-in window manager (`xwayland = builtin`). It is behind the `xwayland` build tag, so `go test ./...` and `make check` only compile it (`go vet -tags xwayland`). It needs `Xwayland` on `PATH` and a GPU, and skips without Xwayland. | 67 | `make e2e-xwayland` runs the end-to-end test of the built-in window manager (`xwayland = builtin`). It is behind the `xwayland` build tag, so `go test ./...` and `make check` only compile it (`go vet -tags xwayland`). It needs `Xwayland` on `PATH` and a GPU, and skips without Xwayland. | ||
| 68 | 68 | ||||
| 69 | - | The test starts a headless NeferWL with a real `Xwayland` and runs `internal/app/testdata/x11probe`, a small X11 client (`-class`, `-title`, `-size`, `-sleep`) that paints its window green, prints `mapped WxH` and `focus`, and exits 0 on `WM_DELETE_WINDOW`. It checks: | 69 | + | The test starts a headless NeferWL with a real `Xwayland` on the first free X display (a live session's `:0` stays untouched) and runs `internal/app/testdata/x11probe`, a small X11 client (`-class`, `-title`, `-size`, `-sleep`) that paints its window green, prints `mapped WxH` and `focus`, and exits 0 on `WM_DELETE_WINDOW`. It checks: |
| 70 | 70 | ||||
| 71 | - the state lists one visible `X11Probe` window with the probe's pid, and the screenshot is mostly green inside its tile; | 71 | - the state lists one visible `X11Probe` window with the probe's pid, and the screenshot is mostly green inside its tile; | ||
| 72 | - the probe receives focus; | 72 | - the probe receives focus; | ||
M internal/adapters/wayland/xwm/atoms.go +2 -2
| @@ -1,7 +1,7 @@ | |||
| 1 | 1 | package xwm | |
| 2 | 2 | ||
| 3 | - | // Atoms interned at boot, in this fixed order. Clipboard and selection atoms | |
| 4 | - | // are interned now so later phases add no round trip. | |
| 3 | + | // Atoms interned at boot in one round trip, in this fixed order. The table | |
| 4 | + | // includes the clipboard and selection atoms. | |
| 5 | 5 | const ( | |
| 6 | 6 | atomWMProtocols = iota | |
| 7 | 7 | atomWMDeleteWindow | |
| @@ -1,7 +1,7 @@ | |||||
| 1 | package xwm | 1 | package xwm | ||
| 2 | 2 | ||||
| 3 | - | // Atoms interned at boot, in this fixed order. Clipboard and selection atoms | 3 | + | // Atoms interned at boot in one round trip, in this fixed order. The table |
| 4 | - | // are interned now so later phases add no round trip. | 4 | + | // includes the clipboard and selection atoms. |
| 5 | const ( | 5 | const ( | ||
| 6 | atomWMProtocols = iota | 6 | atomWMProtocols = iota | ||
| 7 | atomWMDeleteWindow | 7 | atomWMDeleteWindow | ||
M internal/adapters/wayland/xwm/configure_test.go +8 -8
| @@ -15,8 +15,8 @@ func newWin(t *testing.T, x *XWM, p *xpeer, h *mockhost, xid uint32) Slot { | |||
| 15 | 15 | t.Helper() | |
| 16 | 16 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(xid)).Once() | |
| 17 | 17 | p.createNotify(xid, false) | |
| 18 | - | readUntil(t, x, func() bool { return x.Slot(xid) != 0 }) | |
| 19 | - | s := x.Slot(xid) | |
| 18 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) != 0 }) | |
| 19 | + | s := x.tab.lookup(xid) | |
| 20 | 20 | r := x.tab.rec(s) | |
| 21 | 21 | r.ready, r.w, r.h = true, 300, 200 | |
| 22 | 22 | return s | |
| @@ -209,7 +209,7 @@ func TestConfigureRequestUnmanagedHonouredVerbatim(t *testing.T) { | |||
| 209 | 209 | x, p, _, _, _ := attached(t) | |
| 210 | 210 | const win = 0x500009 | |
| 211 | 211 | p.createNotify(win, true) | |
| 212 | - | readUntil(t, x, func() bool { return x.Slot(win) != 0 }) | |
| 212 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) != 0 }) | |
| 213 | 213 | n := settle(t, x, p) | |
| 214 | 214 | ||
| 215 | 215 | x.feed(t, p, func() { | |
| @@ -235,7 +235,7 @@ func TestConfigureStaleAndDuplicateDirtySlots(t *testing.T) { | |||
| 235 | 235 | // The window dies with its entry queued; the slot is reused. | |
| 236 | 236 | h.EXPECT().Dissociate(s, true).Once() | |
| 237 | 237 | p.destroyNotify(a) | |
| 238 | - | readUntil(t, x, func() bool { return x.Slot(a) == 0 }) | |
| 238 | + | readUntil(t, x, func() bool { return x.tab.lookup(a) == 0 }) | |
| 239 | 239 | s2 := newWin(t, x, p, h, b) | |
| 240 | 240 | require.Equal(t, s, s2, "LIFO slot reuse") | |
| 241 | 241 | n := len(p.requests()) | |
| @@ -258,13 +258,13 @@ func TestDirtyQueueNeverGrows(t *testing.T) { | |||
| 258 | 258 | xid := uint32(base + i) | |
| 259 | 259 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(1)).Once() | |
| 260 | 260 | p.createNotify(xid, false) | |
| 261 | - | readUntil(t, x, func() bool { return x.Slot(xid) != 0 }) | |
| 262 | - | s := x.Slot(xid) | |
| 261 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) != 0 }) | |
| 262 | + | s := x.tab.lookup(xid) | |
| 263 | 263 | x.tab.rec(s).ready = true | |
| 264 | 264 | x.Configure(s, ports.ConfigureWindow{Width: 10, Height: 10}) | |
| 265 | 265 | h.EXPECT().Dissociate(s, true).Once() | |
| 266 | 266 | p.destroyNotify(xid) | |
| 267 | - | readUntil(t, x, func() bool { return x.Slot(xid) == 0 }) | |
| 267 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) == 0 }) | |
| 268 | 268 | } | |
| 269 | 269 | require.Equal(t, c0, cap(x.dirty)) | |
| 270 | 270 | require.LessOrEqual(t, len(x.dirty), c0) | |
| @@ -431,7 +431,7 @@ func TestDestroyedActiveWindowClearsActive(t *testing.T) { | |||
| 431 | 431 | settle(t, x, p) | |
| 432 | 432 | h.EXPECT().Dissociate(s, true).Once() | |
| 433 | 433 | p.destroyNotify(win) | |
| 434 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | |
| 434 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) | |
| 435 | 435 | settle(t, x, p) | |
| 436 | 436 | require.Zero(t, x.active) | |
| 437 | 437 | act, _ := p.prop(peerRoot, "_NET_ACTIVE_WINDOW") | |
| @@ -15,8 +15,8 @@ func newWin(t *testing.T, x *XWM, p *xpeer, h *mockhost, xid uint32) Slot { | |||||
| 15 | t.Helper() | 15 | t.Helper() | ||
| 16 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(xid)).Once() | 16 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(xid)).Once() | ||
| 17 | p.createNotify(xid, false) | 17 | p.createNotify(xid, false) | ||
| 18 | - | readUntil(t, x, func() bool { return x.Slot(xid) != 0 }) | 18 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) != 0 }) |
| 19 | - | s := x.Slot(xid) | 19 | + | s := x.tab.lookup(xid) |
| 20 | r := x.tab.rec(s) | 20 | r := x.tab.rec(s) | ||
| 21 | r.ready, r.w, r.h = true, 300, 200 | 21 | r.ready, r.w, r.h = true, 300, 200 | ||
| 22 | return s | 22 | return s | ||
| @@ -209,7 +209,7 @@ func TestConfigureRequestUnmanagedHonouredVerbatim(t *testing.T) { | |||||
| 209 | x, p, _, _, _ := attached(t) | 209 | x, p, _, _, _ := attached(t) | ||
| 210 | const win = 0x500009 | 210 | const win = 0x500009 | ||
| 211 | p.createNotify(win, true) | 211 | p.createNotify(win, true) | ||
| 212 | - | readUntil(t, x, func() bool { return x.Slot(win) != 0 }) | 212 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) != 0 }) |
| 213 | n := settle(t, x, p) | 213 | n := settle(t, x, p) | ||
| 214 | 214 | ||||
| 215 | x.feed(t, p, func() { | 215 | x.feed(t, p, func() { | ||
| @@ -235,7 +235,7 @@ func TestConfigureStaleAndDuplicateDirtySlots(t *testing.T) { | |||||
| 235 | // The window dies with its entry queued; the slot is reused. | 235 | // The window dies with its entry queued; the slot is reused. | ||
| 236 | h.EXPECT().Dissociate(s, true).Once() | 236 | h.EXPECT().Dissociate(s, true).Once() | ||
| 237 | p.destroyNotify(a) | 237 | p.destroyNotify(a) | ||
| 238 | - | readUntil(t, x, func() bool { return x.Slot(a) == 0 }) | 238 | + | readUntil(t, x, func() bool { return x.tab.lookup(a) == 0 }) |
| 239 | s2 := newWin(t, x, p, h, b) | 239 | s2 := newWin(t, x, p, h, b) | ||
| 240 | require.Equal(t, s, s2, "LIFO slot reuse") | 240 | require.Equal(t, s, s2, "LIFO slot reuse") | ||
| 241 | n := len(p.requests()) | 241 | n := len(p.requests()) | ||
| @@ -258,13 +258,13 @@ func TestDirtyQueueNeverGrows(t *testing.T) { | |||||
| 258 | xid := uint32(base + i) | 258 | xid := uint32(base + i) | ||
| 259 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(1)).Once() | 259 | h.EXPECT().Created(mock.Anything, xid).Return(ports.WindowID(1)).Once() | ||
| 260 | p.createNotify(xid, false) | 260 | p.createNotify(xid, false) | ||
| 261 | - | readUntil(t, x, func() bool { return x.Slot(xid) != 0 }) | 261 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) != 0 }) |
| 262 | - | s := x.Slot(xid) | 262 | + | s := x.tab.lookup(xid) |
| 263 | x.tab.rec(s).ready = true | 263 | x.tab.rec(s).ready = true | ||
| 264 | x.Configure(s, ports.ConfigureWindow{Width: 10, Height: 10}) | 264 | x.Configure(s, ports.ConfigureWindow{Width: 10, Height: 10}) | ||
| 265 | h.EXPECT().Dissociate(s, true).Once() | 265 | h.EXPECT().Dissociate(s, true).Once() | ||
| 266 | p.destroyNotify(xid) | 266 | p.destroyNotify(xid) | ||
| 267 | - | readUntil(t, x, func() bool { return x.Slot(xid) == 0 }) | 267 | + | readUntil(t, x, func() bool { return x.tab.lookup(xid) == 0 }) |
| 268 | } | 268 | } | ||
| 269 | require.Equal(t, c0, cap(x.dirty)) | 269 | require.Equal(t, c0, cap(x.dirty)) | ||
| 270 | require.LessOrEqual(t, len(x.dirty), c0) | 270 | require.LessOrEqual(t, len(x.dirty), c0) | ||
| @@ -431,7 +431,7 @@ func TestDestroyedActiveWindowClearsActive(t *testing.T) { | |||||
| 431 | settle(t, x, p) | 431 | settle(t, x, p) | ||
| 432 | h.EXPECT().Dissociate(s, true).Once() | 432 | h.EXPECT().Dissociate(s, true).Once() | ||
| 433 | p.destroyNotify(win) | 433 | p.destroyNotify(win) | ||
| 434 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | 434 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) |
| 435 | settle(t, x, p) | 435 | settle(t, x, p) | ||
| 436 | require.Zero(t, x.active) | 436 | require.Zero(t, x.active) | ||
| 437 | act, _ := p.prop(peerRoot, "_NET_ACTIVE_WINDOW") | 437 | act, _ := p.prop(peerRoot, "_NET_ACTIVE_WINDOW") | ||
M internal/adapters/wayland/xwm/fixes_test.go +2 -2
| @@ -132,7 +132,7 @@ func TestGetGeometryBadDrawableIsNotReady(t *testing.T) { | |||
| 132 | 132 | require.False(t, hs.x.tab.rec(s).ready) | |
| 133 | 133 | hs.h.EXPECT().Dissociate(s, true).Once() | |
| 134 | 134 | hs.p.destroyNotify(win) | |
| 135 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | |
| 135 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) | |
| 136 | 136 | } | |
| 137 | 137 | ||
| 138 | 138 | // A host that refocuses the window while dissociating it must not leave a | |
| @@ -143,7 +143,7 @@ func TestForgetWindowClearsActiveSetByHost(t *testing.T) { | |||
| 143 | 143 | s := newWin(t, x, p, h, win) | |
| 144 | 144 | h.EXPECT().Dissociate(s, true).Run(func(sl Slot, _ bool) { x.Focus(sl) }).Once() | |
| 145 | 145 | p.destroyNotify(win) | |
| 146 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | |
| 146 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) | |
| 147 | 147 | require.Zero(t, x.active) | |
| 148 | 148 | require.False(t, x.refocus) | |
| 149 | 149 | settle(t, x, p) | |
| @@ -132,7 +132,7 @@ func TestGetGeometryBadDrawableIsNotReady(t *testing.T) { | |||||
| 132 | require.False(t, hs.x.tab.rec(s).ready) | 132 | require.False(t, hs.x.tab.rec(s).ready) | ||
| 133 | hs.h.EXPECT().Dissociate(s, true).Once() | 133 | hs.h.EXPECT().Dissociate(s, true).Once() | ||
| 134 | hs.p.destroyNotify(win) | 134 | hs.p.destroyNotify(win) | ||
| 135 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | 135 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) |
| 136 | } | 136 | } | ||
| 137 | 137 | ||||
| 138 | // A host that refocuses the window while dissociating it must not leave a | 138 | // A host that refocuses the window while dissociating it must not leave a | ||
| @@ -143,7 +143,7 @@ func TestForgetWindowClearsActiveSetByHost(t *testing.T) { | |||||
| 143 | s := newWin(t, x, p, h, win) | 143 | s := newWin(t, x, p, h, win) | ||
| 144 | h.EXPECT().Dissociate(s, true).Run(func(sl Slot, _ bool) { x.Focus(sl) }).Once() | 144 | h.EXPECT().Dissociate(s, true).Run(func(sl Slot, _ bool) { x.Focus(sl) }).Once() | ||
| 145 | p.destroyNotify(win) | 145 | p.destroyNotify(win) | ||
| 146 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | 146 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) |
| 147 | require.Zero(t, x.active) | 147 | require.Zero(t, x.active) | ||
| 148 | require.False(t, x.refocus) | 148 | require.False(t, x.refocus) | ||
| 149 | settle(t, x, p) | 149 | settle(t, x, p) | ||
M internal/adapters/wayland/xwm/mapflow_test.go +18 -18
| @@ -50,8 +50,8 @@ func (hs *harness) create(win uint32) Slot { | |||
| 50 | 50 | hs.t.Helper() | |
| 51 | 51 | hs.expectCreated(win) | |
| 52 | 52 | hs.p.createNotify(win, false) | |
| 53 | - | readUntil(hs.t, hs.x, func() bool { return hs.x.Slot(win) != 0 }) | |
| 54 | - | return hs.x.Slot(win) | |
| 53 | + | readUntil(hs.t, hs.x, func() bool { return hs.x.tab.lookup(win) != 0 }) | |
| 54 | + | return hs.x.tab.lookup(win) | |
| 55 | 55 | } | |
| 56 | 56 | ||
| 57 | 57 | // mapAndWait creates and maps win and waits for Ready. | |
| @@ -247,7 +247,7 @@ func TestMapFlowPIDFromXRes(t *testing.T) { | |||
| 247 | 247 | readUntil(t, hs.x, func() bool { _, ok := hs.ready[win]; return ok }) | |
| 248 | 248 | require.Equal(t, 777, hs.ready[win].PID, "Ready waited for the QueryClientIds reply") | |
| 249 | 249 | require.Equal(t, 1, hs.count(func(r xpeerReq) bool { return r.major == 144 && r.minor == 4 })) | |
| 250 | - | require.Zero(t, hs.x.tab.rec(hs.x.Slot(win)).pending) | |
| 250 | + | require.Zero(t, hs.x.tab.rec(hs.x.tab.lookup(win)).pending) | |
| 251 | 251 | } | |
| 252 | 252 | ||
| 253 | 253 | func TestMapFlowPIDUnknownStillReady(t *testing.T) { | |
| @@ -293,7 +293,7 @@ func TestMapFlowBadWindowOnPropertiesNeverReady(t *testing.T) { | |||
| 293 | 293 | ||
| 294 | 294 | hs.h.EXPECT().Dissociate(s, true).Once() | |
| 295 | 295 | hs.p.destroyNotify(win) | |
| 296 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | |
| 296 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) | |
| 297 | 297 | } | |
| 298 | 298 | ||
| 299 | 299 | func TestMapRequestTwiceBeforeReadyAsksOnce(t *testing.T) { | |
| @@ -518,10 +518,10 @@ func TestPairingDuplicateSerialIgnored(t *testing.T) { | |||
| 518 | 518 | func TestPairingUnmanagedKeepsSurfaceWithoutAssociate(t *testing.T) { | |
| 519 | 519 | hs := newHarness(t, nil) | |
| 520 | 520 | hs.p.createNotify(0x500009, true) | |
| 521 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | |
| 521 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) | |
| 522 | 522 | hs.serialMsg(0x500009, 3) | |
| 523 | 523 | hs.x.SetSerial(5, 3) // the mock fails on an Associate | |
| 524 | - | require.EqualValues(t, 5, hs.x.tab.rec(hs.x.Slot(0x500009)).surface) | |
| 524 | + | require.EqualValues(t, 5, hs.x.tab.rec(hs.x.tab.lookup(0x500009)).surface) | |
| 525 | 525 | } | |
| 526 | 526 | ||
| 527 | 527 | func TestPairingTableOverflowDropsOldest(t *testing.T) { | |
| @@ -620,7 +620,7 @@ func TestDestroyWhileMappingNeverReady(t *testing.T) { | |||
| 620 | 620 | hs.waitMap(win) | |
| 621 | 621 | hs.h.EXPECT().Dissociate(s, true).Once() | |
| 622 | 622 | hs.p.destroyNotify(win) | |
| 623 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | |
| 623 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) | |
| 624 | 624 | replies := hs.x.Stats().Replies | |
| 625 | 625 | hs.p.release() // replies for a window that is gone: xturbo retired their slots | |
| 626 | 626 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | |
| @@ -638,12 +638,12 @@ func TestStaleRepliesAfterSlotReuseAreIgnored(t *testing.T) { | |||
| 638 | 638 | hs.waitMap(old) | |
| 639 | 639 | hs.h.EXPECT().Dissociate(s, true).Once() | |
| 640 | 640 | hs.p.destroyNotify(old) | |
| 641 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(old) == 0 }) | |
| 641 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(old) == 0 }) | |
| 642 | 642 | ||
| 643 | 643 | hs.expectCreated(fresh) | |
| 644 | 644 | hs.p.createNotify(fresh, false) | |
| 645 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(fresh) != 0 }) | |
| 646 | - | require.Equal(t, s, hs.x.Slot(fresh), "the freed slot is reused") | |
| 645 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(fresh) != 0 }) | |
| 646 | + | require.Equal(t, s, hs.x.tab.lookup(fresh), "the freed slot is reused") | |
| 647 | 647 | ||
| 648 | 648 | hs.p.release() | |
| 649 | 649 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | |
| @@ -669,7 +669,7 @@ func TestReparentAwayFromRootRemovesManagedWindow(t *testing.T) { | |||
| 669 | 669 | s := hs.mapAndWait(win) | |
| 670 | 670 | hs.h.EXPECT().Dissociate(s, true).Once() | |
| 671 | 671 | hs.p.reparentNotify(win, 0x600000) | |
| 672 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | |
| 672 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) | |
| 673 | 673 | list, _ := hs.p.prop(peerRoot, "_NET_CLIENT_LIST") | |
| 674 | 674 | require.Empty(t, list.data) | |
| 675 | 675 | require.Zero(t, hs.x.tab.n) | |
| @@ -678,9 +678,9 @@ func TestReparentAwayFromRootRemovesManagedWindow(t *testing.T) { | |||
| 678 | 678 | func TestReparentAwayOfUnmanagedWindowRemovesIt(t *testing.T) { | |
| 679 | 679 | hs := newHarness(t, nil) | |
| 680 | 680 | hs.p.createNotify(0x500009, true) | |
| 681 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | |
| 681 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) | |
| 682 | 682 | hs.p.reparentNotify(0x500009, 0x600000) | |
| 683 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) == 0 }) | |
| 683 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) == 0 }) | |
| 684 | 684 | } | |
| 685 | 685 | ||
| 686 | 686 | func TestReparentIntoRootAdoptsWindow(t *testing.T) { | |
| @@ -688,8 +688,8 @@ func TestReparentIntoRootAdoptsWindow(t *testing.T) { | |||
| 688 | 688 | const win = 0x500001 | |
| 689 | 689 | hs.expectCreated(win) | |
| 690 | 690 | hs.p.reparentNotify(win, peerRoot) | |
| 691 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) != 0 }) | |
| 692 | - | require.Equal(t, kindManaged, hs.x.tab.rec(hs.x.Slot(win)).kind) | |
| 691 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) != 0 }) | |
| 692 | + | require.Equal(t, kindManaged, hs.x.tab.rec(hs.x.tab.lookup(win)).kind) | |
| 693 | 693 | ||
| 694 | 694 | // Already known: no second Created. | |
| 695 | 695 | hs.p.reparentNotify(win, peerRoot) | |
| @@ -704,15 +704,15 @@ func TestReparentIntoRootOfOverrideRedirectWindowStaysUnmanaged(t *testing.T) { | |||
| 704 | 704 | binary.LittleEndian.PutUint32(b[12:], peerRoot) | |
| 705 | 705 | b[20] = 1 | |
| 706 | 706 | }) | |
| 707 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | |
| 708 | - | require.Equal(t, kindUnmanaged, hs.x.tab.rec(hs.x.Slot(0x500009)).kind) | |
| 707 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) | |
| 708 | + | require.Equal(t, kindUnmanaged, hs.x.tab.rec(hs.x.tab.lookup(0x500009)).kind) | |
| 709 | 709 | } | |
| 710 | 710 | ||
| 711 | 711 | func TestReparentOfWMWindowIgnored(t *testing.T) { | |
| 712 | 712 | hs := newHarness(t, nil) | |
| 713 | 713 | hs.p.reparentNotify(hs.x.wmWin, peerRoot) | |
| 714 | 714 | readUntil(t, hs.x, func() bool { return hs.x.Stats().Events >= 1 }) | |
| 715 | - | require.Zero(t, hs.x.Slot(hs.x.wmWin)) | |
| 715 | + | require.Zero(t, hs.x.tab.lookup(hs.x.wmWin)) | |
| 716 | 716 | } | |
| 717 | 717 | ||
| 718 | 718 | // Window known only before Attach: Attach replays the map flow. | |
| @@ -50,8 +50,8 @@ func (hs *harness) create(win uint32) Slot { | |||||
| 50 | hs.t.Helper() | 50 | hs.t.Helper() | ||
| 51 | hs.expectCreated(win) | 51 | hs.expectCreated(win) | ||
| 52 | hs.p.createNotify(win, false) | 52 | hs.p.createNotify(win, false) | ||
| 53 | - | readUntil(hs.t, hs.x, func() bool { return hs.x.Slot(win) != 0 }) | 53 | + | readUntil(hs.t, hs.x, func() bool { return hs.x.tab.lookup(win) != 0 }) |
| 54 | - | return hs.x.Slot(win) | 54 | + | return hs.x.tab.lookup(win) |
| 55 | } | 55 | } | ||
| 56 | 56 | ||||
| 57 | // mapAndWait creates and maps win and waits for Ready. | 57 | // mapAndWait creates and maps win and waits for Ready. | ||
| @@ -247,7 +247,7 @@ func TestMapFlowPIDFromXRes(t *testing.T) { | |||||
| 247 | readUntil(t, hs.x, func() bool { _, ok := hs.ready[win]; return ok }) | 247 | readUntil(t, hs.x, func() bool { _, ok := hs.ready[win]; return ok }) | ||
| 248 | require.Equal(t, 777, hs.ready[win].PID, "Ready waited for the QueryClientIds reply") | 248 | require.Equal(t, 777, hs.ready[win].PID, "Ready waited for the QueryClientIds reply") | ||
| 249 | require.Equal(t, 1, hs.count(func(r xpeerReq) bool { return r.major == 144 && r.minor == 4 })) | 249 | require.Equal(t, 1, hs.count(func(r xpeerReq) bool { return r.major == 144 && r.minor == 4 })) | ||
| 250 | - | require.Zero(t, hs.x.tab.rec(hs.x.Slot(win)).pending) | 250 | + | require.Zero(t, hs.x.tab.rec(hs.x.tab.lookup(win)).pending) |
| 251 | } | 251 | } | ||
| 252 | 252 | ||||
| 253 | func TestMapFlowPIDUnknownStillReady(t *testing.T) { | 253 | func TestMapFlowPIDUnknownStillReady(t *testing.T) { | ||
| @@ -293,7 +293,7 @@ func TestMapFlowBadWindowOnPropertiesNeverReady(t *testing.T) { | |||||
| 293 | 293 | ||||
| 294 | hs.h.EXPECT().Dissociate(s, true).Once() | 294 | hs.h.EXPECT().Dissociate(s, true).Once() | ||
| 295 | hs.p.destroyNotify(win) | 295 | hs.p.destroyNotify(win) | ||
| 296 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | 296 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) |
| 297 | } | 297 | } | ||
| 298 | 298 | ||||
| 299 | func TestMapRequestTwiceBeforeReadyAsksOnce(t *testing.T) { | 299 | func TestMapRequestTwiceBeforeReadyAsksOnce(t *testing.T) { | ||
| @@ -518,10 +518,10 @@ func TestPairingDuplicateSerialIgnored(t *testing.T) { | |||||
| 518 | func TestPairingUnmanagedKeepsSurfaceWithoutAssociate(t *testing.T) { | 518 | func TestPairingUnmanagedKeepsSurfaceWithoutAssociate(t *testing.T) { | ||
| 519 | hs := newHarness(t, nil) | 519 | hs := newHarness(t, nil) | ||
| 520 | hs.p.createNotify(0x500009, true) | 520 | hs.p.createNotify(0x500009, true) | ||
| 521 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | 521 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) |
| 522 | hs.serialMsg(0x500009, 3) | 522 | hs.serialMsg(0x500009, 3) | ||
| 523 | hs.x.SetSerial(5, 3) // the mock fails on an Associate | 523 | hs.x.SetSerial(5, 3) // the mock fails on an Associate | ||
| 524 | - | require.EqualValues(t, 5, hs.x.tab.rec(hs.x.Slot(0x500009)).surface) | 524 | + | require.EqualValues(t, 5, hs.x.tab.rec(hs.x.tab.lookup(0x500009)).surface) |
| 525 | } | 525 | } | ||
| 526 | 526 | ||||
| 527 | func TestPairingTableOverflowDropsOldest(t *testing.T) { | 527 | func TestPairingTableOverflowDropsOldest(t *testing.T) { | ||
| @@ -620,7 +620,7 @@ func TestDestroyWhileMappingNeverReady(t *testing.T) { | |||||
| 620 | hs.waitMap(win) | 620 | hs.waitMap(win) | ||
| 621 | hs.h.EXPECT().Dissociate(s, true).Once() | 621 | hs.h.EXPECT().Dissociate(s, true).Once() | ||
| 622 | hs.p.destroyNotify(win) | 622 | hs.p.destroyNotify(win) | ||
| 623 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | 623 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) |
| 624 | replies := hs.x.Stats().Replies | 624 | replies := hs.x.Stats().Replies | ||
| 625 | hs.p.release() // replies for a window that is gone: xturbo retired their slots | 625 | hs.p.release() // replies for a window that is gone: xturbo retired their slots | ||
| 626 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | 626 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | ||
| @@ -638,12 +638,12 @@ func TestStaleRepliesAfterSlotReuseAreIgnored(t *testing.T) { | |||||
| 638 | hs.waitMap(old) | 638 | hs.waitMap(old) | ||
| 639 | hs.h.EXPECT().Dissociate(s, true).Once() | 639 | hs.h.EXPECT().Dissociate(s, true).Once() | ||
| 640 | hs.p.destroyNotify(old) | 640 | hs.p.destroyNotify(old) | ||
| 641 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(old) == 0 }) | 641 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(old) == 0 }) |
| 642 | 642 | ||||
| 643 | hs.expectCreated(fresh) | 643 | hs.expectCreated(fresh) | ||
| 644 | hs.p.createNotify(fresh, false) | 644 | hs.p.createNotify(fresh, false) | ||
| 645 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(fresh) != 0 }) | 645 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(fresh) != 0 }) |
| 646 | - | require.Equal(t, s, hs.x.Slot(fresh), "the freed slot is reused") | 646 | + | require.Equal(t, s, hs.x.tab.lookup(fresh), "the freed slot is reused") |
| 647 | 647 | ||||
| 648 | hs.p.release() | 648 | hs.p.release() | ||
| 649 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | 649 | readUntil(t, hs.x, func() bool { return hs.x.conn.Stats().DroppedReplies >= uint64(propCount) }) | ||
| @@ -669,7 +669,7 @@ func TestReparentAwayFromRootRemovesManagedWindow(t *testing.T) { | |||||
| 669 | s := hs.mapAndWait(win) | 669 | s := hs.mapAndWait(win) | ||
| 670 | hs.h.EXPECT().Dissociate(s, true).Once() | 670 | hs.h.EXPECT().Dissociate(s, true).Once() | ||
| 671 | hs.p.reparentNotify(win, 0x600000) | 671 | hs.p.reparentNotify(win, 0x600000) | ||
| 672 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) == 0 }) | 672 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) == 0 }) |
| 673 | list, _ := hs.p.prop(peerRoot, "_NET_CLIENT_LIST") | 673 | list, _ := hs.p.prop(peerRoot, "_NET_CLIENT_LIST") | ||
| 674 | require.Empty(t, list.data) | 674 | require.Empty(t, list.data) | ||
| 675 | require.Zero(t, hs.x.tab.n) | 675 | require.Zero(t, hs.x.tab.n) | ||
| @@ -678,9 +678,9 @@ func TestReparentAwayFromRootRemovesManagedWindow(t *testing.T) { | |||||
| 678 | func TestReparentAwayOfUnmanagedWindowRemovesIt(t *testing.T) { | 678 | func TestReparentAwayOfUnmanagedWindowRemovesIt(t *testing.T) { | ||
| 679 | hs := newHarness(t, nil) | 679 | hs := newHarness(t, nil) | ||
| 680 | hs.p.createNotify(0x500009, true) | 680 | hs.p.createNotify(0x500009, true) | ||
| 681 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | 681 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) |
| 682 | hs.p.reparentNotify(0x500009, 0x600000) | 682 | hs.p.reparentNotify(0x500009, 0x600000) | ||
| 683 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) == 0 }) | 683 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) == 0 }) |
| 684 | } | 684 | } | ||
| 685 | 685 | ||||
| 686 | func TestReparentIntoRootAdoptsWindow(t *testing.T) { | 686 | func TestReparentIntoRootAdoptsWindow(t *testing.T) { | ||
| @@ -688,8 +688,8 @@ func TestReparentIntoRootAdoptsWindow(t *testing.T) { | |||||
| 688 | const win = 0x500001 | 688 | const win = 0x500001 | ||
| 689 | hs.expectCreated(win) | 689 | hs.expectCreated(win) | ||
| 690 | hs.p.reparentNotify(win, peerRoot) | 690 | hs.p.reparentNotify(win, peerRoot) | ||
| 691 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(win) != 0 }) | 691 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(win) != 0 }) |
| 692 | - | require.Equal(t, kindManaged, hs.x.tab.rec(hs.x.Slot(win)).kind) | 692 | + | require.Equal(t, kindManaged, hs.x.tab.rec(hs.x.tab.lookup(win)).kind) |
| 693 | 693 | ||||
| 694 | // Already known: no second Created. | 694 | // Already known: no second Created. | ||
| 695 | hs.p.reparentNotify(win, peerRoot) | 695 | hs.p.reparentNotify(win, peerRoot) | ||
| @@ -704,15 +704,15 @@ func TestReparentIntoRootOfOverrideRedirectWindowStaysUnmanaged(t *testing.T) { | |||||
| 704 | binary.LittleEndian.PutUint32(b[12:], peerRoot) | 704 | binary.LittleEndian.PutUint32(b[12:], peerRoot) | ||
| 705 | b[20] = 1 | 705 | b[20] = 1 | ||
| 706 | }) | 706 | }) | ||
| 707 | - | readUntil(t, hs.x, func() bool { return hs.x.Slot(0x500009) != 0 }) | 707 | + | readUntil(t, hs.x, func() bool { return hs.x.tab.lookup(0x500009) != 0 }) |
| 708 | - | require.Equal(t, kindUnmanaged, hs.x.tab.rec(hs.x.Slot(0x500009)).kind) | 708 | + | require.Equal(t, kindUnmanaged, hs.x.tab.rec(hs.x.tab.lookup(0x500009)).kind) |
| 709 | } | 709 | } | ||
| 710 | 710 | ||||
| 711 | func TestReparentOfWMWindowIgnored(t *testing.T) { | 711 | func TestReparentOfWMWindowIgnored(t *testing.T) { | ||
| 712 | hs := newHarness(t, nil) | 712 | hs := newHarness(t, nil) | ||
| 713 | hs.p.reparentNotify(hs.x.wmWin, peerRoot) | 713 | hs.p.reparentNotify(hs.x.wmWin, peerRoot) | ||
| 714 | readUntil(t, hs.x, func() bool { return hs.x.Stats().Events >= 1 }) | 714 | readUntil(t, hs.x, func() bool { return hs.x.Stats().Events >= 1 }) | ||
| 715 | - | require.Zero(t, hs.x.Slot(hs.x.wmWin)) | 715 | + | require.Zero(t, hs.x.tab.lookup(hs.x.wmWin)) |
| 716 | } | 716 | } | ||
| 717 | 717 | ||||
| 718 | // Window known only before Attach: Attach replays the map flow. | 718 | // Window known only before Attach: Attach replays the map flow. | ||
M internal/adapters/wayland/xwm/streams_test.go +3 -3
| @@ -67,7 +67,7 @@ func streamScenario(t *testing.T) *harness { | |||
| 67 | 67 | // The steady state is a focused window: a FocusIn on it is not denied, | |
| 68 | 68 | // so no request depends on how events are batched into flushes. The | |
| 69 | 69 | // poke makes sure the focus requests are out before the peer pauses. | |
| 70 | - | hs.x.Focus(hs.x.Slot(streamWin)) | |
| 70 | + | hs.x.Focus(hs.x.tab.lookup(streamWin)) | |
| 71 | 71 | poke(hs) | |
| 72 | 72 | return hs | |
| 73 | 73 | } | |
| @@ -173,11 +173,11 @@ func replay(t *testing.T, k streamKind) (mallocs uint64, hs *harness) { | |||
| 173 | 173 | func TestPropertyUnchangedAllocations(t *testing.T) { | |
| 174 | 174 | m, hs := replay(t, streamKinds[0]) | |
| 175 | 175 | require.Zero(t, m, "unchanged property cycles must not allocate") | |
| 176 | - | require.Equal(t, "net title", hs.x.tab.rec(hs.x.Slot(streamWin)).title) | |
| 176 | + | require.Equal(t, "net title", hs.x.tab.rec(hs.x.tab.lookup(streamWin)).title) | |
| 177 | 177 | } | |
| 178 | 178 | ||
| 179 | 179 | func TestDispatchAllocations(t *testing.T) { | |
| 180 | 180 | m, hs := replay(t, streamKinds[1]) | |
| 181 | 181 | require.Zero(t, m, "steady-state event dispatch must not allocate") | |
| 182 | - | require.True(t, hs.x.tab.rec(hs.x.Slot(streamWin)).mapped) | |
| 182 | + | require.True(t, hs.x.tab.rec(hs.x.tab.lookup(streamWin)).mapped) | |
| 183 | 183 | } | |
| @@ -67,7 +67,7 @@ func streamScenario(t *testing.T) *harness { | |||||
| 67 | // The steady state is a focused window: a FocusIn on it is not denied, | 67 | // The steady state is a focused window: a FocusIn on it is not denied, | ||
| 68 | // so no request depends on how events are batched into flushes. The | 68 | // so no request depends on how events are batched into flushes. The | ||
| 69 | // poke makes sure the focus requests are out before the peer pauses. | 69 | // poke makes sure the focus requests are out before the peer pauses. | ||
| 70 | - | hs.x.Focus(hs.x.Slot(streamWin)) | 70 | + | hs.x.Focus(hs.x.tab.lookup(streamWin)) |
| 71 | poke(hs) | 71 | poke(hs) | ||
| 72 | return hs | 72 | return hs | ||
| 73 | } | 73 | } | ||
| @@ -173,11 +173,11 @@ func replay(t *testing.T, k streamKind) (mallocs uint64, hs *harness) { | |||||
| 173 | func TestPropertyUnchangedAllocations(t *testing.T) { | 173 | func TestPropertyUnchangedAllocations(t *testing.T) { | ||
| 174 | m, hs := replay(t, streamKinds[0]) | 174 | m, hs := replay(t, streamKinds[0]) | ||
| 175 | require.Zero(t, m, "unchanged property cycles must not allocate") | 175 | require.Zero(t, m, "unchanged property cycles must not allocate") | ||
| 176 | - | require.Equal(t, "net title", hs.x.tab.rec(hs.x.Slot(streamWin)).title) | 176 | + | require.Equal(t, "net title", hs.x.tab.rec(hs.x.tab.lookup(streamWin)).title) |
| 177 | } | 177 | } | ||
| 178 | 178 | ||||
| 179 | func TestDispatchAllocations(t *testing.T) { | 179 | func TestDispatchAllocations(t *testing.T) { | ||
| 180 | m, hs := replay(t, streamKinds[1]) | 180 | m, hs := replay(t, streamKinds[1]) | ||
| 181 | require.Zero(t, m, "steady-state event dispatch must not allocate") | 181 | require.Zero(t, m, "steady-state event dispatch must not allocate") | ||
| 182 | - | require.True(t, hs.x.tab.rec(hs.x.Slot(streamWin)).mapped) | 182 | + | require.True(t, hs.x.tab.rec(hs.x.tab.lookup(streamWin)).mapped) |
| 183 | } | 183 | } | ||
M internal/adapters/wayland/xwm/xwm.go +5 -4
| @@ -335,6 +335,10 @@ func (x *XWM) Close() { | |||
| 335 | 335 | return | |
| 336 | 336 | } | |
| 337 | 337 | x.closed = true | |
| 338 | + | s := x.stats | |
| 339 | + | x.log.Info().Uint64("events", s.Events).Uint64("replies", s.Replies).Uint64("errors", s.Errors). | |
| 340 | + | Uint64("unattributed", s.Unattributed).Uint64("stale", s.Stale).Uint64("ring_full", s.RingFull). | |
| 341 | + | Uint64("legacy_id", s.LegacyID).Uint64("unmanaged_seen", s.UnmanagedSeen).Msg("X11 window management closed") | |
| 338 | 342 | if x.src != nil { | |
| 339 | 343 | x.src.Remove() | |
| 340 | 344 | x.src = nil | |
| @@ -373,12 +377,9 @@ func (x *XWM) fail(err error) { | |||
| 373 | 377 | x.Close() | |
| 374 | 378 | } | |
| 375 | 379 | ||
| 376 | - | // Stats returns the counters. | |
| 380 | + | // Stats returns the counters; Close logs them. | |
| 377 | 381 | func (x *XWM) Stats() Stats { return x.stats } | |
| 378 | 382 | ||
| 379 | - | // Slot returns the slot of the X window xid, or 0. | |
| 380 | - | func (x *XWM) Slot(xid uint32) Slot { return x.tab.lookup(xid) } | |
| 381 | - | ||
| 382 | 383 | func (x *XWM) onReadable() { | |
| 383 | 384 | if x.closed { | |
| 384 | 385 | return | |
| @@ -335,6 +335,10 @@ func (x *XWM) Close() { | |||||
| 335 | return | 335 | return | ||
| 336 | } | 336 | } | ||
| 337 | x.closed = true | 337 | x.closed = true | ||
| 338 | + | s := x.stats | |||
| 339 | + | x.log.Info().Uint64("events", s.Events).Uint64("replies", s.Replies).Uint64("errors", s.Errors). | |||
| 340 | + | Uint64("unattributed", s.Unattributed).Uint64("stale", s.Stale).Uint64("ring_full", s.RingFull). | |||
| 341 | + | Uint64("legacy_id", s.LegacyID).Uint64("unmanaged_seen", s.UnmanagedSeen).Msg("X11 window management closed") | |||
| 338 | if x.src != nil { | 342 | if x.src != nil { | ||
| 339 | x.src.Remove() | 343 | x.src.Remove() | ||
| 340 | x.src = nil | 344 | x.src = nil | ||
| @@ -373,12 +377,9 @@ func (x *XWM) fail(err error) { | |||||
| 373 | x.Close() | 377 | x.Close() | ||
| 374 | } | 378 | } | ||
| 375 | 379 | ||||
| 376 | - | // Stats returns the counters. | 380 | + | // Stats returns the counters; Close logs them. |
| 377 | func (x *XWM) Stats() Stats { return x.stats } | 381 | func (x *XWM) Stats() Stats { return x.stats } | ||
| 378 | 382 | ||||
| 379 | - | // Slot returns the slot of the X window xid, or 0. | |||
| 380 | - | func (x *XWM) Slot(xid uint32) Slot { return x.tab.lookup(xid) } | |||
| 381 | - | ||||
| 382 | func (x *XWM) onReadable() { | 383 | func (x *XWM) onReadable() { | ||
| 383 | if x.closed { | 384 | if x.closed { | ||
| 384 | return | 385 | return | ||
M internal/adapters/wayland/xwm/xwm_test.go +19 -19
| @@ -178,10 +178,10 @@ func TestBootExistingWindows(t *testing.T) { | |||
| 178 | 178 | p.attrs[0x400002] = [2]byte{1, 2} // override-redirect, viewable | |
| 179 | 179 | }) | |
| 180 | 180 | _ = p | |
| 181 | - | require.NotZero(t, x.Slot(0x400001)) | |
| 182 | - | require.NotZero(t, x.Slot(0x400002)) | |
| 183 | - | require.Equal(t, kindManaged, x.tab.rec(x.Slot(0x400001)).kind) | |
| 184 | - | require.Equal(t, kindUnmanaged, x.tab.rec(x.Slot(0x400002)).kind) | |
| 181 | + | require.NotZero(t, x.tab.lookup(0x400001)) | |
| 182 | + | require.NotZero(t, x.tab.lookup(0x400002)) | |
| 183 | + | require.Equal(t, kindManaged, x.tab.rec(x.tab.lookup(0x400001)).kind) | |
| 184 | + | require.Equal(t, kindUnmanaged, x.tab.rec(x.tab.lookup(0x400002)).kind) | |
| 185 | 185 | } | |
| 186 | 186 | ||
| 187 | 187 | // readUntil dispatches the socket until cond holds. | |
| @@ -209,10 +209,10 @@ func TestAttachAnnouncesWindowsFoundAtBoot(t *testing.T) { | |||
| 209 | 209 | }) | |
| 210 | 210 | h := newMockhost(t) | |
| 211 | 211 | src := newMockfdSource(t) | |
| 212 | - | h.EXPECT().Created(x.Slot(0x400001), uint32(0x400001)).Return(ports.WindowID(7)).Once() | |
| 212 | + | h.EXPECT().Created(x.tab.lookup(0x400001), uint32(0x400001)).Return(ports.WindowID(7)).Once() | |
| 213 | 213 | post, _ := newPost() | |
| 214 | 214 | x.attach(src, h, post) | |
| 215 | - | require.Equal(t, ports.WindowID(7), x.tab.rec(x.Slot(0x400001)).id) | |
| 215 | + | require.Equal(t, ports.WindowID(7), x.tab.rec(x.tab.lookup(0x400001)).id) | |
| 216 | 216 | } | |
| 217 | 217 | ||
| 218 | 218 | func attached(t *testing.T) (*XWM, *xpeer, *mockhost, *mockfdSource, *[]func()) { | |
| @@ -230,8 +230,8 @@ func TestCreateAndDestroyManaged(t *testing.T) { | |||
| 230 | 230 | const win = 0x500001 | |
| 231 | 231 | h.EXPECT().Created(mock.Anything, uint32(win)).Return(ports.WindowID(3)).Once() | |
| 232 | 232 | p.createNotify(win, false) | |
| 233 | - | readUntil(t, x, func() bool { return x.Slot(win) != 0 }) | |
| 234 | - | s := x.Slot(win) | |
| 233 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) != 0 }) | |
| 234 | + | s := x.tab.lookup(win) | |
| 235 | 235 | require.Equal(t, kindManaged, x.tab.rec(s).kind) | |
| 236 | 236 | require.Equal(t, ports.WindowID(3), x.tab.rec(s).id) | |
| 237 | 237 | ||
| @@ -241,7 +241,7 @@ func TestCreateAndDestroyManaged(t *testing.T) { | |||
| 241 | 241 | ||
| 242 | 242 | h.EXPECT().Dissociate(s, true).Once() | |
| 243 | 243 | p.destroyNotify(win) | |
| 244 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | |
| 244 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) | |
| 245 | 245 | require.Zero(t, x.tab.n) | |
| 246 | 246 | _ = src | |
| 247 | 247 | } | |
| @@ -253,18 +253,18 @@ func TestOwnWindowNeverAdopted(t *testing.T) { | |||
| 253 | 253 | p.createNotify(x.wmWin, false) | |
| 254 | 254 | const marker = 0x500003 | |
| 255 | 255 | p.createNotify(marker, true) | |
| 256 | - | readUntil(t, x, func() bool { return x.Slot(marker) != 0 }) | |
| 257 | - | require.Zero(t, x.Slot(x.wmWin)) | |
| 256 | + | readUntil(t, x, func() bool { return x.tab.lookup(marker) != 0 }) | |
| 257 | + | require.Zero(t, x.tab.lookup(x.wmWin)) | |
| 258 | 258 | } | |
| 259 | 259 | ||
| 260 | 260 | func TestOverrideRedirectNeverReachesHost(t *testing.T) { | |
| 261 | 261 | x, p, _, _, _ := attached(t) // the mock fails the test on any host call | |
| 262 | 262 | p.createNotify(0x500002, true) | |
| 263 | - | readUntil(t, x, func() bool { return x.Slot(0x500002) != 0 }) | |
| 264 | - | require.Equal(t, kindUnmanaged, x.tab.rec(x.Slot(0x500002)).kind) | |
| 263 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500002) != 0 }) | |
| 264 | + | require.Equal(t, kindUnmanaged, x.tab.rec(x.tab.lookup(0x500002)).kind) | |
| 265 | 265 | require.EqualValues(t, 1, x.Stats().UnmanagedSeen) | |
| 266 | 266 | p.destroyNotify(0x500002) | |
| 267 | - | readUntil(t, x, func() bool { return x.Slot(0x500002) == 0 }) | |
| 267 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500002) == 0 }) | |
| 268 | 268 | } | |
| 269 | 269 | ||
| 270 | 270 | func TestCloseDissociatesEverything(t *testing.T) { | |
| @@ -274,9 +274,9 @@ func TestCloseDissociatesEverything(t *testing.T) { | |||
| 274 | 274 | p.createNotify(win, false) | |
| 275 | 275 | } | |
| 276 | 276 | p.createNotify(0x500003, true) | |
| 277 | - | readUntil(t, x, func() bool { return x.Slot(0x500003) != 0 }) | |
| 278 | - | h.EXPECT().Dissociate(x.Slot(0x500001), true).Once() | |
| 279 | - | h.EXPECT().Dissociate(x.Slot(0x500002), true).Once() | |
| 277 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500003) != 0 }) | |
| 278 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500001), true).Once() | |
| 279 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500002), true).Once() | |
| 280 | 280 | src.EXPECT().Remove().Once() | |
| 281 | 281 | x.Close() | |
| 282 | 282 | x.Close() // idempotent | |
| @@ -288,8 +288,8 @@ func TestEOFClosesXWM(t *testing.T) { | |||
| 288 | 288 | x, p, h, src, _ := attached(t) | |
| 289 | 289 | h.EXPECT().Created(mock.Anything, uint32(0x500001)).Return(ports.WindowID(1)).Once() | |
| 290 | 290 | p.createNotify(0x500001, false) | |
| 291 | - | readUntil(t, x, func() bool { return x.Slot(0x500001) != 0 }) | |
| 292 | - | h.EXPECT().Dissociate(x.Slot(0x500001), true).Once() | |
| 291 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500001) != 0 }) | |
| 292 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500001), true).Once() | |
| 293 | 293 | src.EXPECT().Remove().Once() | |
| 294 | 294 | p.hangup() | |
| 295 | 295 | readUntil(t, x, func() bool { return x.closed }) | |
| @@ -178,10 +178,10 @@ func TestBootExistingWindows(t *testing.T) { | |||||
| 178 | p.attrs[0x400002] = [2]byte{1, 2} // override-redirect, viewable | 178 | p.attrs[0x400002] = [2]byte{1, 2} // override-redirect, viewable | ||
| 179 | }) | 179 | }) | ||
| 180 | _ = p | 180 | _ = p | ||
| 181 | - | require.NotZero(t, x.Slot(0x400001)) | 181 | + | require.NotZero(t, x.tab.lookup(0x400001)) |
| 182 | - | require.NotZero(t, x.Slot(0x400002)) | 182 | + | require.NotZero(t, x.tab.lookup(0x400002)) |
| 183 | - | require.Equal(t, kindManaged, x.tab.rec(x.Slot(0x400001)).kind) | 183 | + | require.Equal(t, kindManaged, x.tab.rec(x.tab.lookup(0x400001)).kind) |
| 184 | - | require.Equal(t, kindUnmanaged, x.tab.rec(x.Slot(0x400002)).kind) | 184 | + | require.Equal(t, kindUnmanaged, x.tab.rec(x.tab.lookup(0x400002)).kind) |
| 185 | } | 185 | } | ||
| 186 | 186 | ||||
| 187 | // readUntil dispatches the socket until cond holds. | 187 | // readUntil dispatches the socket until cond holds. | ||
| @@ -209,10 +209,10 @@ func TestAttachAnnouncesWindowsFoundAtBoot(t *testing.T) { | |||||
| 209 | }) | 209 | }) | ||
| 210 | h := newMockhost(t) | 210 | h := newMockhost(t) | ||
| 211 | src := newMockfdSource(t) | 211 | src := newMockfdSource(t) | ||
| 212 | - | h.EXPECT().Created(x.Slot(0x400001), uint32(0x400001)).Return(ports.WindowID(7)).Once() | 212 | + | h.EXPECT().Created(x.tab.lookup(0x400001), uint32(0x400001)).Return(ports.WindowID(7)).Once() |
| 213 | post, _ := newPost() | 213 | post, _ := newPost() | ||
| 214 | x.attach(src, h, post) | 214 | x.attach(src, h, post) | ||
| 215 | - | require.Equal(t, ports.WindowID(7), x.tab.rec(x.Slot(0x400001)).id) | 215 | + | require.Equal(t, ports.WindowID(7), x.tab.rec(x.tab.lookup(0x400001)).id) |
| 216 | } | 216 | } | ||
| 217 | 217 | ||||
| 218 | func attached(t *testing.T) (*XWM, *xpeer, *mockhost, *mockfdSource, *[]func()) { | 218 | func attached(t *testing.T) (*XWM, *xpeer, *mockhost, *mockfdSource, *[]func()) { | ||
| @@ -230,8 +230,8 @@ func TestCreateAndDestroyManaged(t *testing.T) { | |||||
| 230 | const win = 0x500001 | 230 | const win = 0x500001 | ||
| 231 | h.EXPECT().Created(mock.Anything, uint32(win)).Return(ports.WindowID(3)).Once() | 231 | h.EXPECT().Created(mock.Anything, uint32(win)).Return(ports.WindowID(3)).Once() | ||
| 232 | p.createNotify(win, false) | 232 | p.createNotify(win, false) | ||
| 233 | - | readUntil(t, x, func() bool { return x.Slot(win) != 0 }) | 233 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) != 0 }) |
| 234 | - | s := x.Slot(win) | 234 | + | s := x.tab.lookup(win) |
| 235 | require.Equal(t, kindManaged, x.tab.rec(s).kind) | 235 | require.Equal(t, kindManaged, x.tab.rec(s).kind) | ||
| 236 | require.Equal(t, ports.WindowID(3), x.tab.rec(s).id) | 236 | require.Equal(t, ports.WindowID(3), x.tab.rec(s).id) | ||
| 237 | 237 | ||||
| @@ -241,7 +241,7 @@ func TestCreateAndDestroyManaged(t *testing.T) { | |||||
| 241 | 241 | ||||
| 242 | h.EXPECT().Dissociate(s, true).Once() | 242 | h.EXPECT().Dissociate(s, true).Once() | ||
| 243 | p.destroyNotify(win) | 243 | p.destroyNotify(win) | ||
| 244 | - | readUntil(t, x, func() bool { return x.Slot(win) == 0 }) | 244 | + | readUntil(t, x, func() bool { return x.tab.lookup(win) == 0 }) |
| 245 | require.Zero(t, x.tab.n) | 245 | require.Zero(t, x.tab.n) | ||
| 246 | _ = src | 246 | _ = src | ||
| 247 | } | 247 | } | ||
| @@ -253,18 +253,18 @@ func TestOwnWindowNeverAdopted(t *testing.T) { | |||||
| 253 | p.createNotify(x.wmWin, false) | 253 | p.createNotify(x.wmWin, false) | ||
| 254 | const marker = 0x500003 | 254 | const marker = 0x500003 | ||
| 255 | p.createNotify(marker, true) | 255 | p.createNotify(marker, true) | ||
| 256 | - | readUntil(t, x, func() bool { return x.Slot(marker) != 0 }) | 256 | + | readUntil(t, x, func() bool { return x.tab.lookup(marker) != 0 }) |
| 257 | - | require.Zero(t, x.Slot(x.wmWin)) | 257 | + | require.Zero(t, x.tab.lookup(x.wmWin)) |
| 258 | } | 258 | } | ||
| 259 | 259 | ||||
| 260 | func TestOverrideRedirectNeverReachesHost(t *testing.T) { | 260 | func TestOverrideRedirectNeverReachesHost(t *testing.T) { | ||
| 261 | x, p, _, _, _ := attached(t) // the mock fails the test on any host call | 261 | x, p, _, _, _ := attached(t) // the mock fails the test on any host call | ||
| 262 | p.createNotify(0x500002, true) | 262 | p.createNotify(0x500002, true) | ||
| 263 | - | readUntil(t, x, func() bool { return x.Slot(0x500002) != 0 }) | 263 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500002) != 0 }) |
| 264 | - | require.Equal(t, kindUnmanaged, x.tab.rec(x.Slot(0x500002)).kind) | 264 | + | require.Equal(t, kindUnmanaged, x.tab.rec(x.tab.lookup(0x500002)).kind) |
| 265 | require.EqualValues(t, 1, x.Stats().UnmanagedSeen) | 265 | require.EqualValues(t, 1, x.Stats().UnmanagedSeen) | ||
| 266 | p.destroyNotify(0x500002) | 266 | p.destroyNotify(0x500002) | ||
| 267 | - | readUntil(t, x, func() bool { return x.Slot(0x500002) == 0 }) | 267 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500002) == 0 }) |
| 268 | } | 268 | } | ||
| 269 | 269 | ||||
| 270 | func TestCloseDissociatesEverything(t *testing.T) { | 270 | func TestCloseDissociatesEverything(t *testing.T) { | ||
| @@ -274,9 +274,9 @@ func TestCloseDissociatesEverything(t *testing.T) { | |||||
| 274 | p.createNotify(win, false) | 274 | p.createNotify(win, false) | ||
| 275 | } | 275 | } | ||
| 276 | p.createNotify(0x500003, true) | 276 | p.createNotify(0x500003, true) | ||
| 277 | - | readUntil(t, x, func() bool { return x.Slot(0x500003) != 0 }) | 277 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500003) != 0 }) |
| 278 | - | h.EXPECT().Dissociate(x.Slot(0x500001), true).Once() | 278 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500001), true).Once() |
| 279 | - | h.EXPECT().Dissociate(x.Slot(0x500002), true).Once() | 279 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500002), true).Once() |
| 280 | src.EXPECT().Remove().Once() | 280 | src.EXPECT().Remove().Once() | ||
| 281 | x.Close() | 281 | x.Close() | ||
| 282 | x.Close() // idempotent | 282 | x.Close() // idempotent | ||
| @@ -288,8 +288,8 @@ func TestEOFClosesXWM(t *testing.T) { | |||||
| 288 | x, p, h, src, _ := attached(t) | 288 | x, p, h, src, _ := attached(t) | ||
| 289 | h.EXPECT().Created(mock.Anything, uint32(0x500001)).Return(ports.WindowID(1)).Once() | 289 | h.EXPECT().Created(mock.Anything, uint32(0x500001)).Return(ports.WindowID(1)).Once() | ||
| 290 | p.createNotify(0x500001, false) | 290 | p.createNotify(0x500001, false) | ||
| 291 | - | readUntil(t, x, func() bool { return x.Slot(0x500001) != 0 }) | 291 | + | readUntil(t, x, func() bool { return x.tab.lookup(0x500001) != 0 }) |
| 292 | - | h.EXPECT().Dissociate(x.Slot(0x500001), true).Once() | 292 | + | h.EXPECT().Dissociate(x.tab.lookup(0x500001), true).Once() |
| 293 | src.EXPECT().Remove().Once() | 293 | src.EXPECT().Remove().Once() | ||
| 294 | p.hangup() | 294 | p.hangup() | ||
| 295 | readUntil(t, x, func() bool { return x.closed }) | 295 | readUntil(t, x, func() bool { return x.closed }) | ||