i3 - improved tiling WM


Always auto center on 'scratchpad show' if window hasn't been repositioned by the user

Patch status: merged

Patch by Sebastian Ullrich

Long description:

This change ensures a scratchpad window is still centered on the screen
if it has first been shown on another screen of a different
resolution. Moving or resizing the scratchpad manually disables this
behavior.

To apply this patch, use:
curl http://cr.i3wm.org/patch/45/raw.patch | git am

b/include/data.h

22
@@ -569,6 +569,8 @@ struct Con {
23
     /** callbacks */
24
     void(*on_remove_child)(Con *);
25
 
26
+    /** not a scratchpad window, auto centered scratchpad window, or
27
+     * user positioned scratchpad window. */
28
     enum {
29
         SCRATCHPAD_NONE = 0,
30
         SCRATCHPAD_FRESH = 1,

b/src/commands.c

35
@@ -592,6 +592,10 @@ static void cmd_resize_floating(I3_CMD, char *way, char *direction, Con *floatin
36
     } else if (strcmp(direction, "left") == 0) {
37
         floating_con->rect.x -= px;
38
     }
39
+
40
+    /* If this is a scratchpad window, don't auto center it from now on. */
41
+    if (floating_con->scratchpad_state == SCRATCHPAD_FRESH)
42
+        floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
43
 }
44
 
45
 static bool cmd_resize_tiling_direction(I3_CMD, Con *current, char *way, char *direction, int ppt) {

b/src/floating.c

50
@@ -409,6 +409,11 @@ void floating_drag_window(Con *con, const xcb_button_press_event_t *event) {
51
 
52
     /* Drag the window */
53
     drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, XCURSOR_CURSOR_MOVE, drag_window_callback, event);
54
+
55
+    /* If this is a scratchpad window, don't auto center it from now on. */
56
+    if (con->scratchpad_state == SCRATCHPAD_FRESH)
57
+        con->scratchpad_state = SCRATCHPAD_CHANGED;
58
+
59
     tree_render();
60
 }
61
 
62
@@ -507,6 +512,10 @@ void floating_resize_window(Con *con, const bool proportional,
63
     struct resize_window_callback_params params = { corner, proportional, event };
64
 
65
     drag_pointer(con, event, XCB_NONE, BORDER_TOP /* irrelevant */, cursor, resize_window_callback, &params);
66
+
67
+    /* If this is a scratchpad window, don't auto center it from now on. */
68
+    if (con->scratchpad_state == SCRATCHPAD_FRESH)
69
+        con->scratchpad_state = SCRATCHPAD_CHANGED;
70
 }
71
 
72
 /*
73
@@ -630,6 +639,11 @@ void floating_reposition(Con *con, Rect newrect) {
74
     con->rect = newrect;
75
 
76
     floating_maybe_reassign_ws(con);
77
+
78
+    /* If this is a scratchpad window, don't auto center it from now on. */
79
+    if (con->scratchpad_state == SCRATCHPAD_FRESH)
80
+        con->scratchpad_state = SCRATCHPAD_CHANGED;
81
+
82
     tree_render();
83
 }
84
 

b/src/scratchpad.c

89
@@ -177,7 +177,6 @@ void scratchpad_show(Con *con) {
90
                       ((output->rect.width / 2.0) - (con->rect.width / 2.0));
91
         con->rect.y = output->rect.y +
92
                       ((output->rect.height / 2.0) - (con->rect.height / 2.0));
93
-        con->scratchpad_state = SCRATCHPAD_CHANGED;
94
     }
95
 
96
     /* Activate active workspace if window is from another workspace to ensure

b/testcases/t/185-scratchpad.t

101
@@ -93,8 +93,7 @@ is(scalar @{$__i3_scratch->{floating_nodes}}, 0, '__i3_scratch ws empty');
102
 ################################################################################
103
 # 3: Verify that 'scratchpad toggle' sends a window to the __i3_scratch
104
 # workspace and sets the scratchpad flag to SCRATCHPAD_FRESH. The window’s size
105
-# and position will be changed (once!) on the next 'scratchpad show' and the
106
-# flag will be changed to SCRATCHPAD_CHANGED.
107
+# and position will be changed on the next 'scratchpad show'.
108
 ################################################################################
109
 
110
 my ($nodes, $focus) = get_ws_content($tmp);
111
@@ -165,10 +164,33 @@ $__i3_scratch = get_ws('__i3_scratch');
112
 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
113
 is(scalar @scratch_nodes, 1, '__i3_scratch contains our window');
114
 
115
-is($scratch_nodes[0]->{scratchpad_state}, 'changed', 'scratchpad_state changed');
116
+################################################################################
117
+# 6: Resizing the window should disable auto centering on scratchpad show
118
+################################################################################
119
+
120
+cmd 'scratchpad show';
121
+
122
+$ws = get_ws($tmp);
123
+is($ws->{floating_nodes}->[0]->{scratchpad_state}, 'fresh',
124
+   'scratchpad_state fresh');
125
+
126
+cmd 'resize grow width 10 px';
127
+cmd 'scratchpad show';
128
+cmd 'scratchpad show';
129
+
130
+$ws = get_ws($tmp);
131
+$scratchrect = $ws->{floating_nodes}->[0]->{rect};
132
+$outputrect = $output->{rect};
133
+
134
+is($ws->{floating_nodes}->[0]->{scratchpad_state}, 'changed',
135
+   'scratchpad_state changed');
136
+is($scratchrect->{width}, $outputrect->{width} * 0.5 + 10, 'scratch width is 50% + 10px');
137
+
138
+cmd 'resize shrink width 10 px';
139
+cmd 'scratchpad show';
140
 
141
 ################################################################################
142
-# 6: Verify that repeated 'scratchpad show' cycle through the stack, that is,
143
+# 7: Verify that repeated 'scratchpad show' cycle through the stack, that is,
144
 # toggling a visible window should insert it at the bottom of the stack of the
145
 # __i3_scratch workspace.
146
 ################################################################################