Skip to content

Commit 4c6bef6

Browse files
committed
feat: support scroll maximize and fullscreen window
1 parent b357834 commit 4c6bef6

7 files changed

Lines changed: 228 additions & 90 deletions

File tree

src/dispatch/bind_define.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,12 @@ int defaultgaps(const Arg *arg) {
8080

8181
int exchange_client(const Arg *arg) {
8282
Client *c = selmon->sel;
83-
if (!c || c->isfloating || c->isfullscreen || c->ismaximizescreen)
83+
if (!c || c->isfloating)
84+
return 0;
85+
86+
if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon))
8487
return 0;
88+
8589
exchange_two_client(c, direction_select(arg));
8690
return 0;
8791
}
@@ -497,7 +501,7 @@ int setlayout(const Arg *arg) {
497501
for (jk = 0; jk < LENGTH(layouts); jk++) {
498502
if (strcmp(layouts[jk].name, arg->v) == 0) {
499503
selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk];
500-
504+
clear_fullscreen_and_maximized_state(selmon);
501505
arrange(selmon, false);
502506
printstatus();
503507
return 0;
@@ -901,7 +905,7 @@ int switch_layout(const Arg *arg) {
901905
break;
902906
}
903907
}
904-
908+
clear_fullscreen_and_maximized_state(selmon);
905909
arrange(selmon, false);
906910
printstatus();
907911
return 0;
@@ -912,6 +916,7 @@ int switch_layout(const Arg *arg) {
912916
selmon->pertag->ltidxs[selmon->pertag->curtag]->name) == 0) {
913917
selmon->pertag->ltidxs[selmon->pertag->curtag] =
914918
jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1];
919+
clear_fullscreen_and_maximized_state(selmon);
915920
arrange(selmon, false);
916921
printstatus();
917922
return 0;

src/ext-protocol/dwl-ipc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client,
258258
index = 0;
259259

260260
monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index];
261+
clear_fullscreen_and_maximized_state(monitor);
261262
arrange(monitor, false);
262263
printstatus();
263264
}

src/fetch/client.h

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Client *center_tiled_select(Monitor *m) {
142142
return target_c;
143143
}
144144
Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
145-
bool align) {
145+
bool ignore_align) {
146146
Client *c = NULL;
147147
Client **tempClients = NULL; // 初始化为 NULL
148148
int last = -1;
@@ -185,21 +185,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
185185

186186
switch (arg->i) {
187187
case UP:
188-
for (int _i = 0; _i <= last; _i++) {
189-
if (tempClients[_i]->geom.y < sel_y &&
190-
tempClients[_i]->geom.x == sel_x &&
191-
tempClients[_i]->mon == tc->mon) {
192-
int dis_x = tempClients[_i]->geom.x - sel_x;
193-
int dis_y = tempClients[_i]->geom.y - sel_y;
194-
long long int tmp_distance =
195-
dis_x * dis_x + dis_y * dis_y; // 计算距离
196-
if (tmp_distance < distance) {
197-
distance = tmp_distance;
198-
tempFocusClients = tempClients[_i];
188+
if (!ignore_align) {
189+
for (int _i = 0; _i <= last; _i++) {
190+
if (tempClients[_i]->geom.y < sel_y &&
191+
tempClients[_i]->geom.x == sel_x &&
192+
tempClients[_i]->mon == tc->mon) {
193+
int dis_x = tempClients[_i]->geom.x - sel_x;
194+
int dis_y = tempClients[_i]->geom.y - sel_y;
195+
long long int tmp_distance =
196+
dis_x * dis_x + dis_y * dis_y; // 计算距离
197+
if (tmp_distance < distance) {
198+
distance = tmp_distance;
199+
tempFocusClients = tempClients[_i];
200+
}
199201
}
200202
}
201203
}
202-
if (!tempFocusClients && !align) {
204+
if (!tempFocusClients) {
203205
for (int _i = 0; _i <= last; _i++) {
204206
if (tempClients[_i]->geom.y < sel_y) {
205207
int dis_x = tempClients[_i]->geom.x - sel_x;
@@ -215,21 +217,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
215217
}
216218
break;
217219
case DOWN:
218-
for (int _i = 0; _i <= last; _i++) {
219-
if (tempClients[_i]->geom.y > sel_y &&
220-
tempClients[_i]->geom.x == sel_x &&
221-
tempClients[_i]->mon == tc->mon) {
222-
int dis_x = tempClients[_i]->geom.x - sel_x;
223-
int dis_y = tempClients[_i]->geom.y - sel_y;
224-
long long int tmp_distance =
225-
dis_x * dis_x + dis_y * dis_y; // 计算距离
226-
if (tmp_distance < distance) {
227-
distance = tmp_distance;
228-
tempFocusClients = tempClients[_i];
220+
if (!ignore_align) {
221+
for (int _i = 0; _i <= last; _i++) {
222+
if (tempClients[_i]->geom.y > sel_y &&
223+
tempClients[_i]->geom.x == sel_x &&
224+
tempClients[_i]->mon == tc->mon) {
225+
int dis_x = tempClients[_i]->geom.x - sel_x;
226+
int dis_y = tempClients[_i]->geom.y - sel_y;
227+
long long int tmp_distance =
228+
dis_x * dis_x + dis_y * dis_y; // 计算距离
229+
if (tmp_distance < distance) {
230+
distance = tmp_distance;
231+
tempFocusClients = tempClients[_i];
232+
}
229233
}
230234
}
231235
}
232-
if (!tempFocusClients && !align) {
236+
if (!tempFocusClients) {
233237
for (int _i = 0; _i <= last; _i++) {
234238
if (tempClients[_i]->geom.y > sel_y) {
235239
int dis_x = tempClients[_i]->geom.x - sel_x;
@@ -245,21 +249,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
245249
}
246250
break;
247251
case LEFT:
248-
for (int _i = 0; _i <= last; _i++) {
249-
if (tempClients[_i]->geom.x < sel_x &&
250-
tempClients[_i]->geom.y == sel_y &&
251-
tempClients[_i]->mon == tc->mon) {
252-
int dis_x = tempClients[_i]->geom.x - sel_x;
253-
int dis_y = tempClients[_i]->geom.y - sel_y;
254-
long long int tmp_distance =
255-
dis_x * dis_x + dis_y * dis_y; // 计算距离
256-
if (tmp_distance < distance) {
257-
distance = tmp_distance;
258-
tempFocusClients = tempClients[_i];
252+
if (!ignore_align) {
253+
for (int _i = 0; _i <= last; _i++) {
254+
if (tempClients[_i]->geom.x < sel_x &&
255+
tempClients[_i]->geom.y == sel_y &&
256+
tempClients[_i]->mon == tc->mon) {
257+
int dis_x = tempClients[_i]->geom.x - sel_x;
258+
int dis_y = tempClients[_i]->geom.y - sel_y;
259+
long long int tmp_distance =
260+
dis_x * dis_x + dis_y * dis_y; // 计算距离
261+
if (tmp_distance < distance) {
262+
distance = tmp_distance;
263+
tempFocusClients = tempClients[_i];
264+
}
259265
}
260266
}
261267
}
262-
if (!tempFocusClients && !align) {
268+
if (!tempFocusClients) {
263269
for (int _i = 0; _i <= last; _i++) {
264270
if (tempClients[_i]->geom.x < sel_x) {
265271
int dis_x = tempClients[_i]->geom.x - sel_x;
@@ -275,21 +281,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
275281
}
276282
break;
277283
case RIGHT:
278-
for (int _i = 0; _i <= last; _i++) {
279-
if (tempClients[_i]->geom.x > sel_x &&
280-
tempClients[_i]->geom.y == sel_y &&
281-
tempClients[_i]->mon == tc->mon) {
282-
int dis_x = tempClients[_i]->geom.x - sel_x;
283-
int dis_y = tempClients[_i]->geom.y - sel_y;
284-
long long int tmp_distance =
285-
dis_x * dis_x + dis_y * dis_y; // 计算距离
286-
if (tmp_distance < distance) {
287-
distance = tmp_distance;
288-
tempFocusClients = tempClients[_i];
284+
if (!ignore_align) {
285+
for (int _i = 0; _i <= last; _i++) {
286+
if (tempClients[_i]->geom.x > sel_x &&
287+
tempClients[_i]->geom.y == sel_y &&
288+
tempClients[_i]->mon == tc->mon) {
289+
int dis_x = tempClients[_i]->geom.x - sel_x;
290+
int dis_y = tempClients[_i]->geom.y - sel_y;
291+
long long int tmp_distance =
292+
dis_x * dis_x + dis_y * dis_y; // 计算距离
293+
if (tmp_distance < distance) {
294+
distance = tmp_distance;
295+
tempFocusClients = tempClients[_i];
296+
}
289297
}
290298
}
291299
}
292-
if (!tempFocusClients && !align) {
300+
if (!tempFocusClients) {
293301
for (int _i = 0; _i <= last; _i++) {
294302
if (tempClients[_i]->geom.x > sel_x) {
295303
int dis_x = tempClients[_i]->geom.x - sel_x;
@@ -317,12 +325,13 @@ Client *direction_select(const Arg *arg) {
317325
if (!tc)
318326
return NULL;
319327

320-
if (tc && (tc->isfullscreen || tc->ismaximizescreen)) {
321-
// 不支持全屏窗口的焦点切换
328+
if (tc && (tc->isfullscreen || tc->ismaximizescreen) &&
329+
(!is_scroller_layout(selmon) || tc->isfloating)) {
322330
return NULL;
323331
}
324332

325-
return find_client_by_direction(tc, arg, true, false);
333+
return find_client_by_direction(
334+
tc, arg, true, is_scroller_layout(selmon) && !selmon->isoverview);
326335
}
327336

328337
/* We probably should change the name of this, it sounds like

src/layout/arrange.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ arrange(Monitor *m, bool want_animation) {
599599
return;
600600
m->visible_clients = 0;
601601
m->visible_tiling_clients = 0;
602+
m->visible_scroll_tiling_clients = 0;
602603
m->has_visible_fullscreen_client = false;
603604

604605
wl_list_for_each(c, &clients, link) {
@@ -619,6 +620,10 @@ arrange(Monitor *m, bool want_animation) {
619620
if (ISTILED(c)) {
620621
m->visible_tiling_clients++;
621622
}
623+
624+
if (ISSCROLLTILED(c)) {
625+
m->visible_scroll_tiling_clients++;
626+
}
622627
}
623628
}
624629

src/layout/horizontal.h

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,38 @@ void deck(Monitor *m) {
189189
}
190190
}
191191

192+
void horizontal_scroll_adjust_fullandmax(Client *c,
193+
struct wlr_box *target_geom) {
194+
Monitor *m = c->mon;
195+
unsigned int cur_gappih = enablegaps ? m->gappih : 0;
196+
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
197+
unsigned int cur_gappov = enablegaps ? m->gappov : 0;
198+
199+
cur_gappih =
200+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
201+
cur_gappoh =
202+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
203+
cur_gappov =
204+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
205+
206+
if (c->isfullscreen) {
207+
target_geom->height = m->m.height;
208+
target_geom->width = m->m.width;
209+
target_geom->y = m->m.y;
210+
return;
211+
}
212+
213+
if (c->ismaximizescreen) {
214+
target_geom->height = m->w.height - 2 * cur_gappov;
215+
target_geom->width = m->w.width - 2 * cur_gappoh;
216+
target_geom->y = m->w.y + cur_gappov;
217+
return;
218+
}
219+
220+
target_geom->height = m->w.height - 2 * cur_gappov;
221+
target_geom->y = m->w.y + (m->w.height - target_geom->height) / 2;
222+
}
223+
192224
// 滚动布局
193225
void scroller(Monitor *m) {
194226
unsigned int i, n, j;
@@ -203,14 +235,17 @@ void scroller(Monitor *m) {
203235
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
204236
unsigned int cur_gappov = enablegaps ? m->gappov : 0;
205237

206-
cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih;
207-
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh;
208-
cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
238+
cur_gappih =
239+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih;
240+
cur_gappoh =
241+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh;
242+
cur_gappov =
243+
smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov;
209244

210245
unsigned int max_client_width =
211246
m->w.width - 2 * scroller_structs - cur_gappih;
212247

213-
n = m->visible_tiling_clients;
248+
n = m->visible_scroll_tiling_clients;
214249

215250
if (n == 0) {
216251
return; // 没有需要处理的客户端,直接返回
@@ -226,13 +261,14 @@ void scroller(Monitor *m) {
226261
// 第二次遍历,填充 tempClients
227262
j = 0;
228263
wl_list_for_each(c, &clients, link) {
229-
if (VISIBLEON(c, m) && ISTILED(c)) {
264+
if (VISIBLEON(c, m) && ISSCROLLTILED(c)) {
230265
tempClients[j] = c;
231266
j++;
232267
}
233268
}
234269

235-
if (n == 1 && !scroller_ignore_proportion_single) {
270+
if (n == 1 && !scroller_ignore_proportion_single &&
271+
!tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) {
236272
c = tempClients[0];
237273

238274
single_proportion = c->scroller_proportion_single > 0.0f
@@ -248,11 +284,10 @@ void scroller(Monitor *m) {
248284
return;
249285
}
250286

251-
if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating &&
252-
!m->sel->ismaximizescreen && !m->sel->isfullscreen) {
287+
if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) {
253288
root_client = m->sel;
254-
} else if (m->prevsel && ISTILED(m->prevsel) && VISIBLEON(m->prevsel, m) &&
255-
!client_is_unmanaged(m->prevsel)) {
289+
} else if (m->prevsel && ISSCROLLTILED(m->prevsel) &&
290+
VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) {
256291
root_client = m->prevsel;
257292
} else {
258293
root_client = center_tiled_select(m);
@@ -289,11 +324,18 @@ void scroller(Monitor *m) {
289324
target_geom.height = m->w.height - 2 * cur_gappov;
290325
target_geom.width = max_client_width * c->scroller_proportion;
291326
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2;
292-
293-
if (need_scroller) {
327+
horizontal_scroll_adjust_fullandmax(tempClients[focus_client_index],
328+
&target_geom);
329+
if (tempClients[focus_client_index]->isfullscreen) {
330+
target_geom.x = m->m.x;
331+
resize(tempClients[focus_client_index], target_geom, 0);
332+
} else if (tempClients[focus_client_index]->ismaximizescreen) {
333+
target_geom.x = m->w.x + cur_gappoh;
334+
resize(tempClients[focus_client_index], target_geom, 0);
335+
} else if (need_scroller) {
294336
if (scroller_focus_center ||
295337
((!m->prevsel ||
296-
(ISTILED(m->prevsel) &&
338+
(ISSCROLLTILED(m->prevsel) &&
297339
(m->prevsel->scroller_proportion * max_client_width) +
298340
(root_client->scroller_proportion * max_client_width) >
299341
m->w.width - 2 * scroller_structs - cur_gappih)) &&
@@ -316,14 +358,17 @@ void scroller(Monitor *m) {
316358
for (i = 1; i <= focus_client_index; i++) {
317359
c = tempClients[focus_client_index - i];
318360
target_geom.width = max_client_width * c->scroller_proportion;
361+
horizontal_scroll_adjust_fullandmax(c, &target_geom);
319362
target_geom.x = tempClients[focus_client_index - i + 1]->geom.x -
320363
cur_gappih - target_geom.width;
364+
321365
resize(c, target_geom, 0);
322366
}
323367

324368
for (i = 1; i < n - focus_client_index; i++) {
325369
c = tempClients[focus_client_index + i];
326370
target_geom.width = max_client_width * c->scroller_proportion;
371+
horizontal_scroll_adjust_fullandmax(c, &target_geom);
327372
target_geom.x = tempClients[focus_client_index + i - 1]->geom.x +
328373
cur_gappih +
329374
tempClients[focus_client_index + i - 1]->geom.width;

0 commit comments

Comments
 (0)