border_resize.go RawHistoryFolder
1package core
2
3import (
4 "context"
5 "slices"
6 "time"
7)
8
9// borderResize retains the original border identity, never the hit zone that
10// moves as its neighbouring tiles resize. saved owns its slices.
11type borderResize struct {
12 core *Core
13 screen *screen
14 ws *Workspace
15 border border
16 btn uint32
17 saved []Column
18}
19
20func newBorderResize(c *Core, s *screen, w *Workspace, b border, button uint32) *borderResize {
21 g := &borderResize{core: c, screen: s, ws: w, border: b, btn: button, saved: slices.Clone(w.Columns)}
22 for i := range g.saved {
23 g.saved[i].Windows = slices.Clone(g.saved[i].Windows)
24 g.saved[i].Shares = slices.Clone(g.saved[i].Shares)
25 }
26 c.focusScreen = c.screenIndex(s.name())
27 return g
28}
29
30func (g *borderResize) button() uint32 { return g.btn }
31func (g *borderResize) cursor() string {
32 if g.border.kind == borderColumn {
33 return "ew-resize"
34 }
35 return "ns-resize"
36}
37
38func (g *borderResize) valid() bool {
39 c, s, w := g.core, g.screen, g.ws
40 if !slices.Contains(c.screens, s) || s.mon.Current() != w || s.mon.previewing() || s.mon.ov.open || w.pinned() || w.fullscreen != 0 || len(w.Columns) != len(g.saved) {
41 return false
42 }
43 for i, col := range w.Columns {
44 if !slices.Equal(col.Windows, g.saved[i].Windows) {
45 return false
46 }
47 }
48 b := g.border
49 if b.col < 0 || b.col >= len(w.Columns) {
50 return false
51 }
52 if b.kind == borderRow {
53 return b.row >= 0 && b.row+1 < len(w.Columns[b.col].Windows)
54 }
55 return b.col+1 < len(w.Columns) && w.laneOf(b.col) == w.laneOf(b.col+1)
56}
57
58func (g *borderResize) motion(ctx context.Context, _ time.Duration) error {
59 c := g.core
60 if !g.valid() {
61 if err := c.abortPointerGrab(ctx); err != nil {
62 return err
63 }
64 return c.publish(ctx)
65 }
66 pos := int(c.cursorX) - g.screen.x
67 if g.border.kind == borderRow {
68 pos = int(c.cursorY) - g.screen.y
69 }
70 if !g.ws.setBorder(g.border, pos) {
71 return nil
72 }
73 return c.publish(ctx)
74}
75
76func (g *borderResize) release(ctx context.Context) error {
77 if err := g.core.publish(ctx); err != nil {
78 return err
79 }
80 return g.core.rehit(ctx)
81}
82
83func (g *borderResize) cancel() {
84 if !g.valid() {
85 return
86 }
87 for i, saved := range g.saved {
88 col := &g.ws.Columns[i]
89 col.Span, col.spanStamp, col.Shares = saved.Span, saved.spanStamp, slices.Clone(saved.Shares)
90 }
91}