mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-15 14:33:34 -04:00
Compare commits
29 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d81ca73ea1 | ||
|
|
55d366daf2 | ||
|
|
ba014d5059 | ||
|
|
b0fb99b95e | ||
|
|
fa24c606a0 | ||
|
|
8ca013e6c3 | ||
|
|
8a3d065cc1 | ||
|
|
2a9c38df1f | ||
|
|
4daab9e4d5 | ||
|
|
83adb33ad2 | ||
|
|
15fb37f1c6 | ||
|
|
7e178369ff | ||
|
|
792bfac475 | ||
|
|
03e68ba069 | ||
|
|
33cda5afea | ||
|
|
94db68ef88 | ||
|
|
cd6e2883db | ||
|
|
ef59224cdb | ||
|
|
52732c928b | ||
|
|
47f30454e6 | ||
|
|
7faf9b6239 | ||
|
|
36398a1af2 | ||
|
|
a429420b73 | ||
|
|
b8fa9a3043 | ||
|
|
009e2d2111 | ||
|
|
27f4f64173 | ||
|
|
ccb58a4f1a | ||
|
|
db8d22ae8e | ||
|
|
3ab2780b84 |
19 changed files with 453 additions and 457 deletions
|
|
@ -21,6 +21,7 @@ description: Advanced settings for XWayland, focus behavior, and system integrat
|
|||
| `sloppyfocus` | `1` | Focus follows the mouse cursor. |
|
||||
| `warpcursor` | `1` | Warp the cursor to the center of the window when focus changes via keyboard. |
|
||||
| `cursor_hide_timeout` | `0` | Hide the cursor after `N` seconds of inactivity (`0` to disable). |
|
||||
| `cursor_hide_on_keypress` | `0` | Hide the cursor on keypress. |
|
||||
| `drag_tile_to_tile` | `0` | Allow dragging a tiled window onto another to swap their positions. |
|
||||
| `drag_tile_small` | `1` | Allow dragging a tiled window temporarily to small size.|
|
||||
| `drag_corner` | `3` | Corner for drag-to-tile detection (0: none, 1–3: corners, 4: auto-detect). |
|
||||
|
|
@ -48,4 +49,4 @@ description: Advanced settings for XWayland, focus behavior, and system integrat
|
|||
| `idleinhibit_ignore_visible` | `0` | Allow invisible clients (e.g., background audio players) to inhibit idle. |
|
||||
| `tag_carousel` | `0` | Enable tag carousel (cycling through tags). |
|
||||
| `drag_tile_refresh_interval` | `8.0` | Interval (1.0–16.0) to refresh tiled window resize during drag. Too small may cause application lag. |
|
||||
| `drag_floating_refresh_interval` | `8.0` | Interval (1.0–16.0) to refresh floating window resize during drag. Too small may cause application lag. |
|
||||
| `drag_floating_refresh_interval` | `8.0` | Interval (1.0–16.0) to refresh floating window resize during drag. Too small may cause application lag. |
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ Some GPUs have compatibility issues with `syncobj_enable=1` — it may crash app
|
|||
## Power Management
|
||||
|
||||
You can control monitor power using the `mmsg` IPC tool.
|
||||
> Notice: This command does not remove the monitor, it only turns it off.
|
||||
> if you want completely remove monitor, just use `wlr-randr`
|
||||
|
||||
```bash
|
||||
# Turn off
|
||||
|
|
@ -178,13 +180,13 @@ mmsg dispatch toggle_monitor,eDP-1
|
|||
You can also use `wlr-randr` for monitor management:
|
||||
|
||||
```bash
|
||||
# Turn off monitor
|
||||
# remove a monitor
|
||||
wlr-randr --output eDP-1 --off
|
||||
|
||||
# Turn on monitor
|
||||
# add a monitor
|
||||
wlr-randr --output eDP-1 --on
|
||||
|
||||
# Show all monitors
|
||||
# Show all monitors spec
|
||||
wlr-randr
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ Instead, compose your own workflow from small Wayland utilities and bind them to
|
|||
| [`slurp`](https://github.com/emersion/slurp) | Interactively select a region for `grim` |
|
||||
| [`wl-copy`](https://github.com/bugaevc/wl-clipboard) | Copy screenshots directly to the clipboard |
|
||||
| [`satty`](https://github.com/gabm/Satty) | Annotate screenshots before saving |
|
||||
| [`wayfreeze`](https://github.com/nicbk/wayfreeze) | Freeze the screen before capture |
|
||||
| [`wayfreeze`](https://github.com/Jappie3/wayfreeze) | Freeze the screen before capture |
|
||||
|
||||
Install the required with your package manager or from source.
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ windowrule=width:1000,height:900,appid:yesplaymusic,title:Demons
|
|||
|
||||
# Global keybindings for OBS Studio
|
||||
windowrule=globalkeybinding:ctrl+alt-o,appid:com.obsproject.Studio
|
||||
windowrule=globalkeybinding:ctrl+alt+n,appid:com.obsproject.Studio
|
||||
windowrule=globalkeybinding:ctrl+alt-n,appid:com.obsproject.Studio
|
||||
windowrule=isopensilent:1,appid:com.obsproject.Studio
|
||||
|
||||
# Force tearing for games
|
||||
|
|
@ -183,6 +183,9 @@ tagrule=id:Values,monitor_make:xxx,monitor_model:xxx,Parameter:Values
|
|||
| `no_hide` | integer | `0` / `1` | Not hide even if the tag is empty |
|
||||
| `nmaster` | integer | 0, 99 | Number of master windows |
|
||||
| `mfact` | float | 0.1–0.9 | Master area factor |
|
||||
| `scroller_default_proportion` | float | 0.1-1.0 | Set scroller default proportion. |
|
||||
| `scroller_default_proportion_single` | float | 0.1-1.0 | Set scroller auto adjust proportion when it is single window(only apply when set `scroller_ignore_proportion_single` to `0`) |
|
||||
| `scroller_ignore_proportion_single` | integer | `0` / `1` | Ignore scroller single proportion setting. |
|
||||
|
||||
### Examples
|
||||
|
||||
|
|
@ -204,6 +207,10 @@ tagrule=id:4,monitor_name:eDP-1,no_hide:1,layout_name:scroller
|
|||
# Advanced tag configuration with master layout settings
|
||||
tagrule=id:5,layout_name:tile,nmaster:2,mfact:0.6
|
||||
tagrule=id:6,monitor_name:HDMI-A-1,layout_name:monocle,no_render_border:1
|
||||
|
||||
# set scroller proportion for specific tag
|
||||
tagrule=id:1,layout_name:scroller,scroller_default_proportion_single:0.5,scroller_ignore_proportion_single:0,scroller_default_proportion:0.9,monitor_name:HDMI-A-1
|
||||
|
||||
```
|
||||
|
||||
> **Tip:** For Waybar configuration with persistent tags, see [Status Bar](/docs/visuals/status-bar) documentation.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
project('mango', ['c'],
|
||||
version : '0.14.1',
|
||||
version : '0.14.3',
|
||||
)
|
||||
|
||||
subdir('protocols')
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ static void finish_exchange_arrange_and_focus(Client *c1, Client *c2,
|
|||
}
|
||||
|
||||
void client_tile_resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||
if (!ISSCROLLTILED(c))
|
||||
if (!ISFAKETILED(c))
|
||||
return;
|
||||
|
||||
if (!c->isfullscreen && !c->ismaximizescreen) {
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ void apply_border(Client *c) {
|
|||
|
||||
if (c->isfullscreen) {
|
||||
if (c->border->node.enabled) {
|
||||
wlr_scene_node_set_position(&c->scene_surface->node, 0, 0);
|
||||
wlr_scene_node_set_enabled(&c->border->node, false);
|
||||
}
|
||||
return;
|
||||
|
|
@ -698,17 +699,6 @@ void client_set_drop_area(Client *c) {
|
|||
bool dwindle_familiar =
|
||||
cur_layout->id == DWINDLE && config.dwindle_drop_simple_split;
|
||||
|
||||
uint32_t nmaster = c->mon->pertag->nmasters[c->mon->pertag->curtag];
|
||||
|
||||
bool should_swap =
|
||||
(cur_layout->id == DECK || cur_layout->id == VERTICAL_DECK ||
|
||||
cur_layout->id == MONOCLE || cur_layout->id == GRID ||
|
||||
cur_layout->id == FAIR || cur_layout->id == VERTICAL_FAIR ||
|
||||
cur_layout->id == VERTICAL_GRID) ||
|
||||
((cur_layout->id == TILE || cur_layout->id == VERTICAL_TILE ||
|
||||
cur_layout->id == CENTER_TILE || cur_layout->id == RIGHT_TILE) &&
|
||||
nmaster == 1 && c->ismaster);
|
||||
|
||||
if (dwindle_familiar) {
|
||||
bool split_h = c->geom.width >= c->geom.height;
|
||||
float ratio = config.dwindle_split_ratio;
|
||||
|
|
@ -742,42 +732,87 @@ void client_set_drop_area(Client *c) {
|
|||
client_height - (int32_t)(client_height * ratio);
|
||||
}
|
||||
}
|
||||
} else if (should_swap) {
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height;
|
||||
drop_direction = UNDIR;
|
||||
} else if (cur_layout->id == TILE || cur_layout->id == DECK ||
|
||||
cur_layout->id == CENTER_TILE || cur_layout->id == RIGHT_TILE) {
|
||||
if (rel_y < client_height * 0.5) {
|
||||
drop_direction = UP;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
|
||||
if (c->ismaster) {
|
||||
if (c->mon->visible_tiling_clients == 1) {
|
||||
if (rel_x < client_width * 0.5) {
|
||||
drop_direction = LEFT;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
} else {
|
||||
drop_direction = RIGHT;
|
||||
drop_box.x = bw + client_width / 2;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
}
|
||||
} else {
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height;
|
||||
drop_direction = UNDIR;
|
||||
}
|
||||
} else {
|
||||
drop_direction = DOWN;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw + client_height / 2;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
if (rel_y < client_height * 0.5) {
|
||||
drop_direction = UP;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
} else {
|
||||
drop_direction = DOWN;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw + client_height / 2;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
}
|
||||
}
|
||||
} else if (cur_layout->id == VERTICAL_TILE ||
|
||||
cur_layout->id == VERTICAL_DECK) {
|
||||
if (rel_x < client_width * 0.5) {
|
||||
drop_direction = LEFT;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
if (c->ismaster) {
|
||||
if (c->mon->visible_tiling_clients == 1) {
|
||||
if (rel_y < client_height * 0.5) {
|
||||
drop_direction = UP;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
} else {
|
||||
drop_direction = DOWN;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw + client_height / 2;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height / 2;
|
||||
}
|
||||
} else {
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width;
|
||||
drop_box.height = client_height;
|
||||
drop_direction = UNDIR;
|
||||
}
|
||||
|
||||
} else {
|
||||
drop_direction = RIGHT;
|
||||
drop_box.x = bw + client_width / 2;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
if (rel_x < client_width * 0.5) {
|
||||
drop_direction = LEFT;
|
||||
drop_box.x = bw;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
} else {
|
||||
drop_direction = RIGHT;
|
||||
drop_box.x = bw + client_width / 2;
|
||||
drop_box.y = bw;
|
||||
drop_box.width = client_width / 2;
|
||||
drop_box.height = client_height;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
double dist_left = rel_x;
|
||||
double dist_right = client_width - rel_x;
|
||||
|
|
|
|||
|
|
@ -117,6 +117,9 @@ void set_arrange_hidden(Monitor *m, Client *c, bool want_animation) {
|
|||
c->animation.tagining = false;
|
||||
set_tagout_animation(m, c);
|
||||
} else {
|
||||
c->animation.running = false;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, false);
|
||||
c->animainit_geom = c->current = c->pending = c->animation.current =
|
||||
c->geom;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,9 @@ typedef struct {
|
|||
char *monitor_serial;
|
||||
float mfact;
|
||||
int32_t nmaster;
|
||||
float scroller_default_proportion;
|
||||
float scroller_default_proportion_single;
|
||||
int32_t scroller_ignore_proportion_single;
|
||||
int32_t no_render_border;
|
||||
int32_t open_as_floating;
|
||||
int32_t no_hide;
|
||||
|
|
@ -261,6 +264,7 @@ typedef struct {
|
|||
int32_t overviewgappi;
|
||||
int32_t overviewgappo;
|
||||
uint32_t cursor_hide_timeout;
|
||||
uint32_t cursor_hide_on_keypress;
|
||||
|
||||
uint32_t axis_bind_apply_timeout;
|
||||
uint32_t focus_on_activate;
|
||||
|
|
@ -1714,6 +1718,8 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
config->overviewgappo = atoi(value);
|
||||
} else if (strcmp(key, "cursor_hide_timeout") == 0) {
|
||||
config->cursor_hide_timeout = atoi(value);
|
||||
} else if (strcmp(key, "cursor_hide_on_keypress") == 0) {
|
||||
config->cursor_hide_on_keypress = atoi(value);
|
||||
} else if (strcmp(key, "axis_bind_apply_timeout") == 0) {
|
||||
config->axis_bind_apply_timeout = atoi(value);
|
||||
} else if (strcmp(key, "focus_on_activate") == 0) {
|
||||
|
|
@ -2038,6 +2044,9 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
rule->no_render_border = 0;
|
||||
rule->open_as_floating = 0;
|
||||
rule->no_hide = 0;
|
||||
rule->scroller_default_proportion = 0.0f;
|
||||
rule->scroller_default_proportion_single = 0.0f;
|
||||
rule->scroller_ignore_proportion_single = -1;
|
||||
|
||||
bool parse_error = false;
|
||||
char *token = strtok(value, ",");
|
||||
|
|
@ -2073,6 +2082,17 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
rule->nmaster = CLAMP_INT(atoi(val), 1, 99);
|
||||
} else if (strcmp(key, "mfact") == 0) {
|
||||
rule->mfact = CLAMP_FLOAT(atof(val), 0.1f, 0.9f);
|
||||
} else if (strcmp(key, "scroller_default_proportion") == 0) {
|
||||
rule->scroller_default_proportion =
|
||||
CLAMP_FLOAT(atof(val), 0.0f, 1.0f);
|
||||
} else if (strcmp(key, "scroller_default_proportion_single") ==
|
||||
0) {
|
||||
rule->scroller_default_proportion_single =
|
||||
CLAMP_FLOAT(atof(val), 0.0f, 1.0f);
|
||||
} else if (strcmp(key, "scroller_ignore_proportion_single") ==
|
||||
0) {
|
||||
rule->scroller_ignore_proportion_single =
|
||||
CLAMP_INT(atoi(val), 0, 1);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
||||
|
|
@ -3346,6 +3366,8 @@ void override_config(void) {
|
|||
CLAMP_INT(config.no_radius_when_single, 0, 1);
|
||||
config.cursor_hide_timeout =
|
||||
CLAMP_INT(config.cursor_hide_timeout, 0, 36000);
|
||||
config.cursor_hide_on_keypress =
|
||||
CLAMP_INT(config.cursor_hide_on_keypress, 0, 1);
|
||||
config.single_scratchpad = CLAMP_INT(config.single_scratchpad, 0, 1);
|
||||
config.repeat_rate = CLAMP_INT(config.repeat_rate, 1, 1000);
|
||||
config.repeat_delay = CLAMP_INT(config.repeat_delay, 1, 20000);
|
||||
|
|
@ -3507,6 +3529,7 @@ void set_value_default() {
|
|||
config.overviewgappi = 5;
|
||||
config.overviewgappo = 30;
|
||||
config.cursor_hide_timeout = 0;
|
||||
config.cursor_hide_on_keypress = 0;
|
||||
|
||||
config.warpcursor = 1;
|
||||
config.drag_corner = 3;
|
||||
|
|
@ -3928,6 +3951,12 @@ void parse_tagrule(Monitor *m) {
|
|||
for (i = 0; i <= LENGTH(tags); i++) {
|
||||
m->pertag->nmasters[i] = config.default_nmaster;
|
||||
m->pertag->mfacts[i] = config.default_mfact;
|
||||
m->pertag->scroller_default_proportion[i] =
|
||||
config.scroller_default_proportion;
|
||||
m->pertag->scroller_default_proportion_single[i] =
|
||||
config.scroller_default_proportion_single;
|
||||
m->pertag->scroller_ignore_proportion_single[i] =
|
||||
config.scroller_ignore_proportion_single;
|
||||
}
|
||||
|
||||
for (i = 0; i < config.tag_rules_count; i++) {
|
||||
|
|
@ -3982,6 +4011,15 @@ void parse_tagrule(Monitor *m) {
|
|||
m->pertag->no_render_border[tr.id] = tr.no_render_border;
|
||||
if (tr.open_as_floating >= 0)
|
||||
m->pertag->open_as_floating[tr.id] = tr.open_as_floating;
|
||||
if (tr.scroller_default_proportion > 0.0f)
|
||||
m->pertag->scroller_default_proportion[tr.id] =
|
||||
tr.scroller_default_proportion;
|
||||
if (tr.scroller_default_proportion_single > 0.0f)
|
||||
m->pertag->scroller_default_proportion_single[tr.id] =
|
||||
tr.scroller_default_proportion_single;
|
||||
if (tr.scroller_ignore_proportion_single >= 0)
|
||||
m->pertag->scroller_ignore_proportion_single[tr.id] =
|
||||
tr.scroller_ignore_proportion_single;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1355,9 +1355,9 @@ int32_t togglefullscreen(const Arg *arg) {
|
|||
sel->isnamedscratchpad = 0;
|
||||
|
||||
if (sel->isfullscreen)
|
||||
setfullscreen(sel, 0);
|
||||
setfullscreen(sel, 0, true);
|
||||
else
|
||||
setfullscreen(sel, 1);
|
||||
setfullscreen(sel, 1, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1401,9 +1401,9 @@ int32_t togglemaximizescreen(const Arg *arg) {
|
|||
sel->isnamedscratchpad = 0;
|
||||
|
||||
if (sel->ismaximizescreen)
|
||||
setmaximizescreen(sel, 0);
|
||||
setmaximizescreen(sel, 0, true);
|
||||
else
|
||||
setmaximizescreen(sel, 1);
|
||||
setmaximizescreen(sel, 1, true);
|
||||
|
||||
setborder_color(sel);
|
||||
return 0;
|
||||
|
|
@ -1760,7 +1760,12 @@ int32_t toggleoverview(const Arg *arg) {
|
|||
|
||||
if (selmon->isoverview) {
|
||||
wlr_seat_pointer_clear_focus(seat);
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
|
||||
if (cursor_hidden) {
|
||||
handlecursoractivity();
|
||||
} else {
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
}
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c && c->mon == selmon && !client_is_unmanaged(c) &&
|
||||
|
|
@ -1913,7 +1918,7 @@ int32_t scroller_stack(const Arg *arg) {
|
|||
if (!c || !c->mon || c->isfloating || !is_scroller_layout(selmon))
|
||||
return 0;
|
||||
|
||||
Client *target_client = find_client_by_direction(c, arg, false, true);
|
||||
Client *target_client = find_client_by_direction(c, arg, false);
|
||||
|
||||
return scroller_apply_stack(c, target_client, arg->i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,10 +188,10 @@ void refresh_monitors_workspaces_status(Monitor *m) {
|
|||
int32_t i;
|
||||
|
||||
if (m->isoverview) {
|
||||
add_workspace_by_tag(0, m);
|
||||
for (i = 1; i <= LENGTH(tags); i++) {
|
||||
remove_workspace_by_tag(i, m);
|
||||
}
|
||||
add_workspace_by_tag(0, m);
|
||||
} else {
|
||||
remove_workspace_by_tag(0, m);
|
||||
for (i = 1; i <= LENGTH(tags); i++) {
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ void handle_foreign_maximize_request(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
|
||||
if (c->ismaximizescreen && !event->maximized) {
|
||||
setmaximizescreen(c, 0);
|
||||
setmaximizescreen(c, 0, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->ismaximizescreen && event->maximized) {
|
||||
setmaximizescreen(c, 1);
|
||||
setmaximizescreen(c, 1, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -59,12 +59,12 @@ void handle_foreign_fullscreen_request(struct wl_listener *listener,
|
|||
return;
|
||||
|
||||
if (c->isfullscreen && !event->fullscreen) {
|
||||
setfullscreen(c, 0);
|
||||
setfullscreen(c, 0, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->isfullscreen && event->fullscreen) {
|
||||
setfullscreen(c, 1);
|
||||
setfullscreen(c, 1, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,9 +91,9 @@ setclient_coordinate_center(Client *c, Monitor *tm, struct wlr_box geom,
|
|||
if (!m)
|
||||
return geom;
|
||||
|
||||
uint32_t cbw = check_hit_no_border(c) ? c->bw : 0;
|
||||
uint32_t cbw = c && check_hit_no_border(c) ? c->bw : 0;
|
||||
|
||||
if (!c->no_force_center && m) {
|
||||
if ((!c || !c->no_force_center) && m) {
|
||||
tempbox.x = m->w.x + (m->w.width - geom.width) / 2;
|
||||
tempbox.y = m->w.y + (m->w.height - geom.height) / 2;
|
||||
} else {
|
||||
|
|
@ -163,10 +163,11 @@ Client *center_tiled_select(Monitor *m) {
|
|||
}
|
||||
return target_c;
|
||||
}
|
||||
Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
||||
bool ignore_align) {
|
||||
|
||||
Client *find_client_by_direction(Client *tc, const Arg *arg,
|
||||
bool findfloating) {
|
||||
Client *c = NULL;
|
||||
Client **tempClients = NULL; // 初始化为 NULL
|
||||
Client **tempClients = NULL;
|
||||
int32_t last = -1;
|
||||
|
||||
// 第一次遍历,计算客户端数量
|
||||
|
|
@ -179,13 +180,12 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
|||
}
|
||||
|
||||
if (last < 0) {
|
||||
return NULL; // 没有符合条件的客户端
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 动态分配内存
|
||||
tempClients = malloc((last + 1) * sizeof(Client *));
|
||||
if (!tempClients) {
|
||||
// 处理内存分配失败的情况
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -200,249 +200,102 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating,
|
|||
}
|
||||
}
|
||||
|
||||
int32_t sel_x = tc->geom.x;
|
||||
int32_t sel_y = tc->geom.y;
|
||||
// 获取当前窗口的四个边界及中心点
|
||||
int32_t tc_l = tc->geom.x;
|
||||
int32_t tc_r = tc->geom.x + tc->geom.width;
|
||||
int32_t tc_t = tc->geom.y;
|
||||
int32_t tc_b = tc->geom.y + tc->geom.height;
|
||||
int32_t tc_cx = tc_l + tc->geom.width / 2;
|
||||
int32_t tc_cy = tc_t + tc->geom.height / 2;
|
||||
|
||||
int64_t distance = LLONG_MAX;
|
||||
int64_t same_monitor_distance = LLONG_MAX;
|
||||
Client *tempFocusClients = NULL;
|
||||
Client *tempSameMonitorFocusClients = NULL;
|
||||
|
||||
switch (arg->i) {
|
||||
case UP:
|
||||
if (!ignore_align) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y < sel_y &&
|
||||
tempClients[_i]->geom.x == sel_x &&
|
||||
tempClients[_i]->mon == tc->mon) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
for (int32_t step = 0; step < 2; step++) {
|
||||
if (step == 1 && tempFocusClients)
|
||||
break;
|
||||
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
c = tempClients[_i];
|
||||
if (c == tc)
|
||||
continue;
|
||||
|
||||
if (step == 0 &&
|
||||
(!client_is_in_same_stack(tc, c, NULL) || c->mon != tc->mon)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取目标窗口的四个边界及中心点
|
||||
int32_t c_l = c->geom.x;
|
||||
int32_t c_r = c->geom.x + c->geom.width;
|
||||
int32_t c_t = c->geom.y;
|
||||
int32_t c_b = c->geom.y + c->geom.height;
|
||||
int32_t c_cx = c_l + c->geom.width / 2;
|
||||
int32_t c_cy = c_t + c->geom.height / 2;
|
||||
|
||||
int64_t main_dist = 0;
|
||||
int64_t orth_dist = 0;
|
||||
bool match_dir = false;
|
||||
|
||||
switch (arg->i) {
|
||||
case LEFT:
|
||||
match_dir = (c_cx < tc_cx && c_l < tc_l);
|
||||
if (match_dir) {
|
||||
main_dist = tc_l - c_r;
|
||||
orth_dist = (c_b < tc_t)
|
||||
? (tc_t - c_b)
|
||||
: ((c_t > tc_b) ? (c_t - tc_b) : 0);
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
match_dir = (c_cx > tc_cx && c_r > tc_r);
|
||||
if (match_dir) {
|
||||
main_dist = c_l - tc_r;
|
||||
orth_dist = (c_b < tc_t)
|
||||
? (tc_t - c_b)
|
||||
: ((c_t > tc_b) ? (c_t - tc_b) : 0);
|
||||
}
|
||||
break;
|
||||
case UP:
|
||||
match_dir = (c_cy < tc_cy && c_t < tc_t);
|
||||
if (match_dir) {
|
||||
main_dist = tc_t - c_b;
|
||||
orth_dist = (c_r < tc_l)
|
||||
? (tc_l - c_r)
|
||||
: ((c_l > tc_r) ? (c_l - tc_r) : 0);
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
match_dir = (c_cy > tc_cy && c_b > tc_b);
|
||||
if (match_dir) {
|
||||
main_dist = c_t - tc_b;
|
||||
orth_dist = (c_r < tc_l)
|
||||
? (tc_l - c_r)
|
||||
: ((c_l > tc_r) ? (c_l - tc_r) : 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (match_dir) {
|
||||
int64_t tmp_distance =
|
||||
main_dist * main_dist + 2 * orth_dist * orth_dist;
|
||||
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = c;
|
||||
}
|
||||
if (c->mon == tc->mon && tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y < sel_y &&
|
||||
tempClients[_i]->mon == tc->mon &&
|
||||
client_is_in_same_stack(tc, tempClients[_i], NULL)) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y < sel_y) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
if (!ignore_align) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y > sel_y &&
|
||||
tempClients[_i]->geom.x == sel_x &&
|
||||
tempClients[_i]->mon == tc->mon) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y > sel_y &&
|
||||
tempClients[_i]->mon == tc->mon &&
|
||||
client_is_in_same_stack(tc, tempClients[_i], NULL)) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.y > sel_y) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LEFT:
|
||||
if (!ignore_align) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x < sel_x &&
|
||||
tempClients[_i]->geom.y == sel_y &&
|
||||
tempClients[_i]->mon == tc->mon) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x < sel_x &&
|
||||
tempClients[_i]->mon == tc->mon &&
|
||||
client_is_in_same_stack(tc, tempClients[_i], NULL)) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x < sel_x) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
if (!ignore_align) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x > sel_x &&
|
||||
tempClients[_i]->geom.y == sel_y &&
|
||||
tempClients[_i]->mon == tc->mon) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x > sel_x &&
|
||||
tempClients[_i]->mon == tc->mon &&
|
||||
client_is_in_same_stack(tc, tempClients[_i], NULL)) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tempFocusClients) {
|
||||
for (int32_t _i = 0; _i <= last; _i++) {
|
||||
if (tempClients[_i]->geom.x > sel_x) {
|
||||
int32_t dis_x = tempClients[_i]->geom.x - sel_x;
|
||||
int32_t dis_y = tempClients[_i]->geom.y - sel_y;
|
||||
int64_t tmp_distance =
|
||||
dis_x * dis_x + dis_y * dis_y; // 计算距离
|
||||
if (tmp_distance < distance) {
|
||||
distance = tmp_distance;
|
||||
tempFocusClients = tempClients[_i];
|
||||
}
|
||||
if (tempClients[_i]->mon == tc->mon &&
|
||||
tmp_distance < same_monitor_distance) {
|
||||
same_monitor_distance = tmp_distance;
|
||||
tempSameMonitorFocusClients = tempClients[_i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
free(tempClients); // 释放内存
|
||||
free(tempClients);
|
||||
|
||||
if (tempSameMonitorFocusClients) {
|
||||
return tempSameMonitorFocusClients;
|
||||
} else {
|
||||
|
|
@ -462,10 +315,7 @@ Client *direction_select(const Arg *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return find_client_by_direction(
|
||||
tc, arg, true,
|
||||
(is_scroller_layout(selmon) || is_centertile_layout(selmon)) &&
|
||||
!selmon->isoverview);
|
||||
return find_client_by_direction(tc, arg, true);
|
||||
}
|
||||
|
||||
/* We probably should change the name of this, it sounds like
|
||||
|
|
|
|||
|
|
@ -160,11 +160,26 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
|||
if (pl)
|
||||
*pl = l;
|
||||
|
||||
if (selmon && selmon->isoverview && (!l || layer_ignores_focus(l))) {
|
||||
if (selmon && selmon->isoverview && config.ov_no_resize) {
|
||||
ovc = xytoclient(x, y);
|
||||
if (pc)
|
||||
*pc = ovc;
|
||||
if (psurface && ovc)
|
||||
*psurface = client_surface(ovc);
|
||||
|
||||
bool is_below = false;
|
||||
if (l && l->layer_surface) {
|
||||
is_below = (l->layer_surface->current.layer ==
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
|
||||
l->layer_surface->current.layer ==
|
||||
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM);
|
||||
}
|
||||
|
||||
if (ovc && (!l || layer_ignores_focus(l) || is_below)) {
|
||||
if (pc)
|
||||
*pc = ovc;
|
||||
|
||||
if (psurface)
|
||||
*psurface = ovc ? client_surface(ovc) : NULL;
|
||||
|
||||
if (pl && ovc)
|
||||
*pl = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,9 @@ void set_size_per(Monitor *m, Client *c) {
|
|||
c->master_inner_per = 1.0f;
|
||||
c->stack_inner_per = 1.0f;
|
||||
}
|
||||
|
||||
c->scroller_proportion =
|
||||
m->pertag->scroller_default_proportion[m->pertag->curtag];
|
||||
}
|
||||
|
||||
void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||
|
|
@ -751,6 +754,7 @@ void resize_tile_grid_fair(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
|
||||
void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
||||
int32_t offsety, uint32_t time, bool isvertical) {
|
||||
|
||||
if (!grabc || grabc->isfullscreen || grabc->ismaximizescreen)
|
||||
return;
|
||||
if (grabc->mon->isoverview)
|
||||
|
|
@ -772,7 +776,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int32_t offsetx,
|
|||
|
||||
Client *stack_head_client = headnode->client;
|
||||
|
||||
if (m->visible_tiling_clients == 1 &&
|
||||
if (m->visible_scroll_tiling_clients == 1 &&
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -500,16 +500,13 @@ void deck(Monitor *m) {
|
|||
return;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
if (VISIBLEON(fc, m) && ISFAKETILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate master width using mfact from pertag
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
// Calculate master width including outer gaps
|
||||
if (n > nmasters)
|
||||
mw = nmasters ? round((m->w.width - 2 * cur_gappoh) * mfact) : 0;
|
||||
else
|
||||
|
|
@ -521,16 +518,15 @@ void deck(Monitor *m) {
|
|||
continue;
|
||||
if (i < nmasters) {
|
||||
c->master_mfact_per = mfact;
|
||||
// Master area clients
|
||||
client_tile_resize(
|
||||
c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
.y = m->w.y + cur_gappov + my,
|
||||
.width = mw,
|
||||
.height = (m->w.height - 2 * cur_gappov - my) /
|
||||
(MIN(n, nmasters) - i)},
|
||||
0);
|
||||
my += c->geom.height;
|
||||
int32_t h =
|
||||
(m->w.height - 2 * cur_gappov - my) / (MIN(n, nmasters) - i);
|
||||
client_tile_resize(c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
.y = m->w.y + cur_gappov + my,
|
||||
.width = mw,
|
||||
.height = h},
|
||||
0);
|
||||
my += h;
|
||||
} else {
|
||||
// Stack area clients
|
||||
c->master_mfact_per = mfact;
|
||||
|
|
@ -588,6 +584,7 @@ void grid(Monitor *m) {
|
|||
int32_t target_gappi = enablegaps ? config.gappih : 0;
|
||||
float single_width_ratio = 0.9;
|
||||
float single_height_ratio = 0.9;
|
||||
struct wlr_box target_geom;
|
||||
|
||||
n = m->visible_fake_tiling_clients;
|
||||
|
||||
|
|
@ -603,11 +600,11 @@ void grid(Monitor *m) {
|
|||
ISFAKETILED(c))) {
|
||||
cw = (m->w.width - 2 * target_gappo) * single_width_ratio;
|
||||
ch = (m->w.height - 2 * target_gappo) * single_height_ratio;
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
c->geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
c->geom.width = cw;
|
||||
c->geom.height = ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
target_geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
target_geom.width = cw;
|
||||
target_geom.height = ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -651,16 +648,16 @@ void grid(Monitor *m) {
|
|||
cw = avail_w * (col_pers[i] / sum_col);
|
||||
|
||||
if (i == 0) {
|
||||
c->geom.x = m->w.x + target_gappo;
|
||||
target_geom.x = m->w.x + target_gappo;
|
||||
} else if (i == 1) {
|
||||
// 第二个窗口的 X 坐标紧跟第一个窗口后面
|
||||
float cw0 = avail_w * (col_pers[0] / sum_col);
|
||||
c->geom.x = m->w.x + target_gappo + cw0 + target_gappi;
|
||||
target_geom.x = m->w.x + target_gappo + cw0 + target_gappi;
|
||||
}
|
||||
c->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
c->geom.width = cw;
|
||||
c->geom.height = ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
target_geom.width = cw;
|
||||
target_geom.height = ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -757,11 +754,11 @@ void grid(Monitor *m) {
|
|||
? (m->w.y + m->w.height - target_gappo - fl_cy)
|
||||
: avail_h * (row_pers[r_idx] / sum_row);
|
||||
|
||||
c->geom.x = (int32_t)fl_cx;
|
||||
c->geom.y = (int32_t)fl_cy;
|
||||
c->geom.width = (int32_t)fl_cw;
|
||||
c->geom.height = (int32_t)fl_ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.x = (int32_t)fl_cx;
|
||||
target_geom.y = (int32_t)fl_cy;
|
||||
target_geom.width = (int32_t)fl_cw;
|
||||
target_geom.height = (int32_t)fl_ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,6 +284,10 @@ void scroller(Monitor *m) {
|
|||
uint32_t tag = m->pertag->curtag;
|
||||
struct TagScrollerState *st = ensure_scroller_state(m, tag);
|
||||
Client *c = NULL;
|
||||
float scroller_default_proportion_single =
|
||||
m->pertag->scroller_default_proportion_single[tag];
|
||||
int32_t scroller_ignore_proportion_single =
|
||||
m->pertag->scroller_ignore_proportion_single[tag];
|
||||
|
||||
/* 按全局客户端链表顺序收集所有堆叠头,确保视觉顺序正确 */
|
||||
struct ScrollerStackNode *heads[64];
|
||||
|
|
@ -323,14 +327,13 @@ void scroller(Monitor *m) {
|
|||
m->w.width - 2 * config.scroller_structs - cur_gappih;
|
||||
|
||||
/* 单客户端特例 */
|
||||
if (n_heads == 1 && !config.scroller_ignore_proportion_single &&
|
||||
if (n_heads == 1 && !scroller_ignore_proportion_single &&
|
||||
!heads[0]->client->isfullscreen &&
|
||||
!heads[0]->client->ismaximizescreen) {
|
||||
struct ScrollerStackNode *head = heads[0];
|
||||
float single_proportion =
|
||||
head->scroller_proportion_single > 0.0f
|
||||
? head->scroller_proportion_single
|
||||
: config.scroller_default_proportion_single;
|
||||
float single_proportion = head->scroller_proportion_single > 0.0f
|
||||
? head->scroller_proportion_single
|
||||
: scroller_default_proportion_single;
|
||||
struct wlr_box target_geom;
|
||||
target_geom.height = m->w.height - 2 * cur_gappov;
|
||||
target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion;
|
||||
|
|
@ -420,7 +423,7 @@ void scroller(Monitor *m) {
|
|||
max_client_width) >
|
||||
m->w.width - 2 * config.scroller_structs - cur_gappih)));
|
||||
|
||||
if (n_heads == 1 && config.scroller_ignore_proportion_single) {
|
||||
if (n_heads == 1 && scroller_ignore_proportion_single) {
|
||||
need_scroller = true;
|
||||
}
|
||||
if (start_drag_window)
|
||||
|
|
@ -507,6 +510,10 @@ void vertical_scroller(Monitor *m) {
|
|||
uint32_t tag = m->pertag->curtag;
|
||||
struct TagScrollerState *st = ensure_scroller_state(m, tag);
|
||||
Client *c = NULL;
|
||||
float scroller_default_proportion_single =
|
||||
m->pertag->scroller_default_proportion_single[tag];
|
||||
int32_t scroller_ignore_proportion_single =
|
||||
m->pertag->scroller_ignore_proportion_single[tag];
|
||||
|
||||
/* 按全局顺序收集堆叠头 */
|
||||
struct ScrollerStackNode *heads[64];
|
||||
|
|
@ -542,14 +549,13 @@ void vertical_scroller(Monitor *m) {
|
|||
int32_t max_client_height =
|
||||
m->w.height - 2 * config.scroller_structs - cur_gappiv;
|
||||
|
||||
if (n_heads == 1 && !config.scroller_ignore_proportion_single &&
|
||||
if (n_heads == 1 && !scroller_ignore_proportion_single &&
|
||||
!heads[0]->client->isfullscreen &&
|
||||
!heads[0]->client->ismaximizescreen) {
|
||||
struct ScrollerStackNode *head = heads[0];
|
||||
float single_proportion =
|
||||
head->scroller_proportion_single > 0.0f
|
||||
? head->scroller_proportion_single
|
||||
: config.scroller_default_proportion_single;
|
||||
float single_proportion = head->scroller_proportion_single > 0.0f
|
||||
? head->scroller_proportion_single
|
||||
: scroller_default_proportion_single;
|
||||
struct wlr_box target_geom;
|
||||
target_geom.width = m->w.width - 2 * cur_gappoh;
|
||||
target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion;
|
||||
|
|
@ -638,7 +644,7 @@ void vertical_scroller(Monitor *m) {
|
|||
max_client_height) >
|
||||
m->w.height - 2 * config.scroller_structs - cur_gappiv)));
|
||||
|
||||
if (n_heads == 1 && config.scroller_ignore_proportion_single) {
|
||||
if (n_heads == 1 && scroller_ignore_proportion_single) {
|
||||
need_scroller = true;
|
||||
}
|
||||
if (start_drag_window)
|
||||
|
|
@ -743,9 +749,9 @@ void scroller_insert_stack(Client *c, Client *target_client,
|
|||
return;
|
||||
|
||||
if (c->isfullscreen)
|
||||
setfullscreen(c, 0);
|
||||
setfullscreen(c, 0, true);
|
||||
if (c->ismaximizescreen)
|
||||
setmaximizescreen(c, 0);
|
||||
setmaximizescreen(c, 0, true);
|
||||
|
||||
Monitor *m = c->mon;
|
||||
uint32_t tag = m->pertag->curtag;
|
||||
|
|
@ -785,9 +791,9 @@ void scroller_insert_stack(Client *c, Client *target_client,
|
|||
head = head->prev_in_stack;
|
||||
Client *stack_head = head->client;
|
||||
if (stack_head->ismaximizescreen)
|
||||
setmaximizescreen(stack_head, 0);
|
||||
setmaximizescreen(stack_head, 0, true);
|
||||
if (stack_head->isfullscreen)
|
||||
setfullscreen(stack_head, 0);
|
||||
setfullscreen(stack_head, 0, true);
|
||||
|
||||
/* 同步到 Client 字段 */
|
||||
sync_scroller_state_to_clients(m, tag);
|
||||
|
|
|
|||
|
|
@ -137,12 +137,10 @@ void vertical_deck(Monitor *m) {
|
|||
return;
|
||||
|
||||
wl_list_for_each(fc, &clients, link) {
|
||||
|
||||
if (VISIBLEON(fc, m) && ISFAKETILED(fc))
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate master width using mfact from pertag
|
||||
mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per
|
||||
: m->pertag->mfacts[m->pertag->curtag];
|
||||
|
||||
|
|
@ -156,16 +154,18 @@ void vertical_deck(Monitor *m) {
|
|||
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
||||
continue;
|
||||
if (i < nmasters) {
|
||||
client_tile_resize(
|
||||
c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh + mx,
|
||||
.y = m->w.y + cur_gappov,
|
||||
.width = (m->w.width - 2 * cur_gappoh - mx) /
|
||||
(MIN(n, nmasters) - i),
|
||||
.height = mh},
|
||||
0);
|
||||
mx += c->geom.width;
|
||||
c->master_mfact_per = mfact;
|
||||
int32_t w =
|
||||
(m->w.width - 2 * cur_gappoh - mx) / (MIN(n, nmasters) - i);
|
||||
client_tile_resize(c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh + mx,
|
||||
.y = m->w.y + cur_gappov,
|
||||
.width = w,
|
||||
.height = mh},
|
||||
0);
|
||||
mx += w;
|
||||
} else {
|
||||
c->master_mfact_per = mfact;
|
||||
client_tile_resize(
|
||||
c,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
|
|
@ -186,14 +186,13 @@ void vertical_grid(Monitor *m) {
|
|||
int32_t cw, ch;
|
||||
int32_t rows, cols, overrows;
|
||||
Client *c = NULL;
|
||||
int32_t target_gappo =
|
||||
enablegaps ? m->isoverview ? config.overviewgappo : config.gappov : 0;
|
||||
int32_t target_gappi =
|
||||
enablegaps ? m->isoverview ? config.overviewgappi : config.gappiv : 0;
|
||||
float single_width_ratio = m->isoverview ? 0.7 : 0.9;
|
||||
float single_height_ratio = m->isoverview ? 0.8 : 0.9;
|
||||
int32_t target_gappo = enablegaps ? config.gappov : 0;
|
||||
int32_t target_gappi = enablegaps ? config.gappiv : 0;
|
||||
float single_width_ratio = 0.9;
|
||||
float single_height_ratio = 0.9;
|
||||
struct wlr_box target_geom;
|
||||
|
||||
n = m->isoverview ? m->visible_clients : m->visible_fake_tiling_clients;
|
||||
n = m->visible_fake_tiling_clients;
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -202,15 +201,14 @@ void vertical_grid(Monitor *m) {
|
|||
if (c->mon != m)
|
||||
continue;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_is_x11_popup(c)) ||
|
||||
ISFAKETILED(c))) {
|
||||
(!client_is_x11_popup(c) || ISFAKETILED(c))) {
|
||||
ch = (m->w.height - 2 * target_gappo) * single_height_ratio;
|
||||
cw = (m->w.width - 2 * target_gappo) * single_width_ratio;
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
c->geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
c->geom.width = cw;
|
||||
c->geom.height = ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
target_geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
target_geom.width = cw;
|
||||
target_geom.height = ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -224,8 +222,7 @@ void vertical_grid(Monitor *m) {
|
|||
if (c->mon != m)
|
||||
continue;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_is_x11_popup(c)) ||
|
||||
ISFAKETILED(c))) {
|
||||
(!client_is_x11_popup(c) || ISFAKETILED(c))) {
|
||||
if (i < 2)
|
||||
row_pers[i] =
|
||||
(c->grid_row_per > 0.0f) ? c->grid_row_per : 1.0f;
|
||||
|
|
@ -242,8 +239,7 @@ void vertical_grid(Monitor *m) {
|
|||
if (c->mon != m)
|
||||
continue;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_is_x11_popup(c)) ||
|
||||
ISFAKETILED(c))) {
|
||||
(!client_is_x11_popup(c) || ISFAKETILED(c))) {
|
||||
c->grid_col_idx = 0;
|
||||
c->grid_row_idx = i;
|
||||
c->grid_col_per = 1.0f;
|
||||
|
|
@ -252,17 +248,17 @@ void vertical_grid(Monitor *m) {
|
|||
// 根据分配的权重动态计算当前窗口的高度
|
||||
ch = avail_h * (row_pers[i] / sum_row);
|
||||
|
||||
c->geom.x = m->w.x + (m->w.width - cw) / 2 + target_gappo;
|
||||
target_geom.x = m->w.x + (m->w.width - cw) / 2 + target_gappo;
|
||||
if (i == 0) {
|
||||
c->geom.y = m->w.y + target_gappo;
|
||||
target_geom.y = m->w.y + target_gappo;
|
||||
} else if (i == 1) {
|
||||
// 第二个窗口的 Y 坐标紧跟第一个窗口下面
|
||||
float ch0 = avail_h * (row_pers[0] / sum_row);
|
||||
c->geom.y = m->w.y + target_gappo + ch0 + target_gappi;
|
||||
target_geom.y = m->w.y + target_gappo + ch0 + target_gappi;
|
||||
}
|
||||
c->geom.width = cw;
|
||||
c->geom.height = ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.width = cw;
|
||||
target_geom.height = ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -287,7 +283,7 @@ void vertical_grid(Monitor *m) {
|
|||
if (c->mon != m)
|
||||
continue;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_is_x11_popup(c)) || ISFAKETILED(c))) {
|
||||
(!client_is_x11_popup(c) || ISFAKETILED(c))) {
|
||||
int32_t c_idx = i / rows;
|
||||
int32_t r_idx = i % rows;
|
||||
if (r_idx == 0)
|
||||
|
|
@ -314,7 +310,7 @@ void vertical_grid(Monitor *m) {
|
|||
if (c->mon != m)
|
||||
continue;
|
||||
if (VISIBLEON(c, m) && !c->isunglobal &&
|
||||
((m->isoverview && !client_is_x11_popup(c)) || ISFAKETILED(c))) {
|
||||
(!client_is_x11_popup(c) || ISFAKETILED(c))) {
|
||||
int32_t c_idx = i / rows;
|
||||
int32_t r_idx = i % rows;
|
||||
|
||||
|
|
@ -352,11 +348,11 @@ void vertical_grid(Monitor *m) {
|
|||
? (m->w.x + m->w.width - target_gappo - fl_cx)
|
||||
: avail_w * (col_pers[c_idx] / sum_col);
|
||||
|
||||
c->geom.x = (int32_t)fl_cx;
|
||||
c->geom.y = (int32_t)fl_cy;
|
||||
c->geom.width = (int32_t)fl_cw;
|
||||
c->geom.height = (int32_t)fl_ch;
|
||||
client_tile_resize(c, c->geom, 0);
|
||||
target_geom.x = (int32_t)fl_cx;
|
||||
target_geom.y = (int32_t)fl_cy;
|
||||
target_geom.width = (int32_t)fl_cw;
|
||||
target_geom.height = (int32_t)fl_ch;
|
||||
client_tile_resize(c, target_geom, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
161
src/mango.c
161
src/mango.c
|
|
@ -735,8 +735,9 @@ static void run(char *startup_cmd);
|
|||
static void setcursor(struct wl_listener *listener, void *data);
|
||||
static void setfloating(Client *c, int32_t floating);
|
||||
static void setfakefullscreen(Client *c, int32_t fakefullscreen);
|
||||
static void setfullscreen(Client *c, int32_t fullscreen);
|
||||
static void setmaximizescreen(Client *c, int32_t maximizescreen);
|
||||
static void setfullscreen(Client *c, int32_t fullscreen, bool rearrange);
|
||||
static void setmaximizescreen(Client *c, int32_t maximizescreen,
|
||||
bool rearrange);
|
||||
static void reset_maximizescreen_size(Client *c);
|
||||
static void setgaps(int32_t oh, int32_t ov, int32_t ih, int32_t iv);
|
||||
|
||||
|
|
@ -855,7 +856,7 @@ static float *get_border_color(Client *c);
|
|||
static void clear_fullscreen_and_maximized_state(Monitor *m);
|
||||
static void request_fresh_all_monitors(void);
|
||||
static Client *find_client_by_direction(Client *tc, const Arg *arg,
|
||||
bool findfloating, bool ignore_align);
|
||||
bool findfloating);
|
||||
static void exit_scroller_stack(Client *c);
|
||||
static Client *scroll_get_stack_head_client(Client *c);
|
||||
static bool client_only_in_one_tag(Client *c);
|
||||
|
|
@ -1026,6 +1027,9 @@ struct Pertag {
|
|||
int32_t no_hide[LENGTH(tags) + 1];
|
||||
int32_t no_render_border[LENGTH(tags) + 1];
|
||||
int32_t open_as_floating[LENGTH(tags) + 1];
|
||||
float scroller_default_proportion[LENGTH(tags) + 1];
|
||||
float scroller_default_proportion_single[LENGTH(tags) + 1];
|
||||
int32_t scroller_ignore_proportion_single[LENGTH(tags) + 1];
|
||||
struct DwindleNode *dwindle_root[LENGTH(tags) + 1];
|
||||
const Layout *ltidxs[LENGTH(tags) + 1];
|
||||
struct TagScrollerState *scroller_state[LENGTH(tags) + 1];
|
||||
|
|
@ -1073,7 +1077,7 @@ static struct wl_listener last_cursor_surface_destroy_listener = {
|
|||
.notify = last_cursor_surface_destroy};
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void fix_xwayland_unmanaged_coordinate(Client *c);
|
||||
static void fix_xwayland_coordinate(struct wlr_box *geom);
|
||||
static int32_t synckeymap(void *data);
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
static void configurex11(struct wl_listener *listener, void *data);
|
||||
|
|
@ -1150,11 +1154,11 @@ void clear_fullscreen_flag(Client *c) {
|
|||
}
|
||||
|
||||
if (c->isfullscreen) {
|
||||
setfullscreen(c, false);
|
||||
setfullscreen(c, false, true);
|
||||
}
|
||||
|
||||
if (c->ismaximizescreen) {
|
||||
setmaximizescreen(c, 0);
|
||||
setmaximizescreen(c, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1615,7 +1619,7 @@ void applyrules(Client *c) {
|
|||
|
||||
#ifdef XWAYLAND
|
||||
if (c->isfloating && client_is_x11(c)) {
|
||||
fix_xwayland_unmanaged_coordinate(c);
|
||||
fix_xwayland_coordinate(&c->geom);
|
||||
c->float_geom = c->geom;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1748,7 +1752,7 @@ void applyrules(Client *c) {
|
|||
view_in_mon(&(Arg){.ui = c->tags}, true, c->mon, true);
|
||||
}
|
||||
|
||||
setfullscreen(c, fullscreen_state_backup);
|
||||
setfullscreen(c, fullscreen_state_backup, true);
|
||||
|
||||
if (c->isfakefullscreen) {
|
||||
setfakefullscreen(c, 1);
|
||||
|
|
@ -2202,9 +2206,10 @@ void hold_end(struct wl_listener *listener, void *data) {
|
|||
Client *find_closest_tiled_client(Client *c) {
|
||||
Client *tc, *closest = NULL;
|
||||
long min_dist = LONG_MAX;
|
||||
Monitor *cursor_mon = xytomon(cursor->x, cursor->y);
|
||||
|
||||
wl_list_for_each(tc, &clients, link) {
|
||||
if (tc == c || !ISTILED(tc) || !VISIBLEON(tc, c->mon))
|
||||
if (tc == c || !ISTILED(tc) || !VISIBLEON(tc, cursor_mon))
|
||||
continue;
|
||||
|
||||
if (cursor->x >= tc->geom.x &&
|
||||
|
|
@ -2236,7 +2241,9 @@ void place_drag_tile_client(Client *c) {
|
|||
|
||||
if (closest->drop_direction == UNDIR) {
|
||||
setfloating(c, 0);
|
||||
exchange_two_client(c, closest);
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(closest->link.prev, &c->link);
|
||||
arrange(closest->mon, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2335,6 +2342,17 @@ bool handle_buttonpress(struct wlr_pointer_button_event *event) {
|
|||
}
|
||||
}
|
||||
|
||||
// overview模式下鼠标左键跳转,右键关闭窗口
|
||||
if (selmon && selmon->isoverview && event->button == BTN_LEFT && c) {
|
||||
toggleoverview(&(Arg){.i = 1});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (selmon && selmon->isoverview && event->button == BTN_RIGHT && c) {
|
||||
pending_kill_client(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 当鼠标焦点在layer上的时候,不检测虚拟键盘的mod状态,
|
||||
// 避免layer虚拟键盘锁死mod按键状态
|
||||
hard_keyboard = &kb_group->wlr_group->keyboard;
|
||||
|
|
@ -2351,16 +2369,6 @@ bool handle_buttonpress(struct wlr_pointer_button_event *event) {
|
|||
break;
|
||||
m = &config.mouse_bindings[ji];
|
||||
|
||||
if (selmon->isoverview && event->button == BTN_LEFT && c) {
|
||||
toggleoverview(&(Arg){.i = 1});
|
||||
return true;
|
||||
}
|
||||
|
||||
if (selmon->isoverview && event->button == BTN_RIGHT && c) {
|
||||
pending_kill_client(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CLEANMASK(mods) == CLEANMASK(m->mod) &&
|
||||
event->button == m->button && m->func &&
|
||||
(CLEANMASK(m->mod) != 0 ||
|
||||
|
|
@ -3140,7 +3148,6 @@ void createlayersurface(struct wl_listener *listener, void *data) {
|
|||
LISTEN(&l->scene->node.events.destroy, &l->destroy, destroylayernodenotify);
|
||||
|
||||
wl_list_insert(&l->mon->layers[layer_surface->pending.layer], &l->link);
|
||||
wlr_surface_send_enter(surface, layer_surface->output);
|
||||
}
|
||||
|
||||
void createlocksurface(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -3940,7 +3947,7 @@ fullscreennotify(struct wl_listener *listener, void *data) {
|
|||
if (!c || c->iskilling)
|
||||
return;
|
||||
|
||||
setfullscreen(c, client_wants_fullscreen(c));
|
||||
setfullscreen(c, client_wants_fullscreen(c), true);
|
||||
}
|
||||
|
||||
void requestmonstate(struct wl_listener *listener, void *data) {
|
||||
|
|
@ -4206,6 +4213,11 @@ void keypress(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
if (config.cursor_hide_on_keypress && !cursor_hidden &&
|
||||
event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
hidecursor(NULL);
|
||||
}
|
||||
|
||||
/* On _press_ if there is no active screen locker,
|
||||
* attempt to process a compositor keybinding. */
|
||||
for (i = 0; i < nsyms; i++)
|
||||
|
|
@ -4469,24 +4481,24 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
/* Handle unmanaged clients first so we can return prior create borders
|
||||
*/
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_unmanaged(c)) {
|
||||
/* Unmanaged clients always are floating */
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
fix_xwayland_unmanaged_coordinate(c);
|
||||
LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry,
|
||||
setgeometrynotify);
|
||||
}
|
||||
#endif
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]);
|
||||
fix_xwayland_coordinate(&c->geom);
|
||||
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x,
|
||||
c->geom.y, c->geom.width,
|
||||
c->geom.height);
|
||||
LISTEN(&c->surface.xwayland->events.set_geometry, &c->set_geometry,
|
||||
setgeometrynotify);
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]);
|
||||
if (client_wants_focus(c)) {
|
||||
focusclient(c, 1);
|
||||
exclusive_focus = c;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
// extra node
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
|
@ -4578,9 +4590,9 @@ void maximizenotify(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
if (client_request_maximize(c, data)) {
|
||||
setmaximizescreen(c, 1);
|
||||
setmaximizescreen(c, 1, true);
|
||||
} else {
|
||||
setmaximizescreen(c, 0);
|
||||
setmaximizescreen(c, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4808,7 +4820,8 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
if (!surface && !seat->drag && !cursor_hidden)
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
|
||||
if (c && c->mon && !c->animation.running && (INSIDEMON(c) || !ISTILED(c))) {
|
||||
if (c && c->mon && !c->animation.running &&
|
||||
(INSIDEMON(c) || !ISSCROLLTILED(c))) {
|
||||
scroller_focus_lock = 0;
|
||||
}
|
||||
|
||||
|
|
@ -4820,13 +4833,15 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
}
|
||||
|
||||
if (!scroller_focus_lock || !(c && c->mon && !INSIDEMON(c))) {
|
||||
if (c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c)) {
|
||||
if (c && c->mon && ISSCROLLTILED(c) && is_scroller_layout(c->mon) &&
|
||||
!INSIDEMON(c)) {
|
||||
should_lock = true;
|
||||
}
|
||||
|
||||
if (!((!config.edge_scroller_pointer_focus ||
|
||||
speed < config.edge_scroller_focus_allow_speed) &&
|
||||
c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c))) {
|
||||
c && c->mon && ISSCROLLTILED(c) && is_scroller_layout(c->mon) &&
|
||||
!INSIDEMON(c))) {
|
||||
pointerfocus(c, surface, sx, sy, time);
|
||||
}
|
||||
|
||||
|
|
@ -5442,7 +5457,7 @@ void exit_scroller_stack(Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
||||
void setmaximizescreen(Client *c, int32_t maximizescreen, bool rearrange) {
|
||||
struct wlr_box maximizescreen_box;
|
||||
if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling)
|
||||
return;
|
||||
|
|
@ -5483,7 +5498,8 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
|
|||
client_set_maximized(c, true);
|
||||
}
|
||||
|
||||
arrange(c->mon, false, false);
|
||||
if (rearrange)
|
||||
arrange(c->mon, false, false);
|
||||
}
|
||||
|
||||
void setfakefullscreen(Client *c, int32_t fakefullscreen) {
|
||||
|
|
@ -5492,12 +5508,13 @@ void setfakefullscreen(Client *c, int32_t fakefullscreen) {
|
|||
return;
|
||||
|
||||
if (c->isfullscreen)
|
||||
setfullscreen(c, 0);
|
||||
setfullscreen(c, 0, true);
|
||||
|
||||
client_set_fullscreen(c, fakefullscreen);
|
||||
}
|
||||
|
||||
void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自带全屏
|
||||
void setfullscreen(Client *c, int32_t fullscreen,
|
||||
bool rearrange) // 用自定义全屏代理自带全屏
|
||||
{
|
||||
|
||||
if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling)
|
||||
|
|
@ -5543,7 +5560,8 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
|
|||
layers[fullscreen || c->isfloating ? LyrTop : LyrTile]);
|
||||
}
|
||||
|
||||
arrange(c->mon, false, false);
|
||||
if (rearrange)
|
||||
arrange(c->mon, false, false);
|
||||
}
|
||||
|
||||
void setgaps(int32_t oh, int32_t ov, int32_t ih, int32_t iv) {
|
||||
|
|
@ -5672,7 +5690,8 @@ void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus) {
|
|||
client_reset_mon_tags(c, m, newtags);
|
||||
check_match_tag_floating_rule(c, m);
|
||||
setfloating(c, c->isfloating);
|
||||
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
|
||||
setfullscreen(c, c->isfullscreen,
|
||||
true); /* This will call arrange(c->mon) */
|
||||
}
|
||||
|
||||
if (focus && !client_is_x11_popup(c)) {
|
||||
|
|
@ -6264,13 +6283,13 @@ void overview_restore(Client *c, const Arg *arg) {
|
|||
resize(c, c->overview_backup_geom, 0);
|
||||
} else if (c->isfullscreen || c->ismaximizescreen) {
|
||||
if (want_restore_fullscreen(c) && c->ismaximizescreen) {
|
||||
setmaximizescreen(c, 1);
|
||||
setmaximizescreen(c, 1, false);
|
||||
} else if (want_restore_fullscreen(c) && c->isfullscreen) {
|
||||
setfullscreen(c, 1);
|
||||
setfullscreen(c, 1, false);
|
||||
} else {
|
||||
client_pending_fullscreen_state(c, 0);
|
||||
client_pending_maximized_state(c, 0);
|
||||
setfullscreen(c, false);
|
||||
setfullscreen(c, false, false);
|
||||
}
|
||||
} else {
|
||||
if (c->is_restoring_from_ov) {
|
||||
|
|
@ -6466,8 +6485,8 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
if (c->swallowedby) {
|
||||
setmaximizescreen(c->swallowedby, c->ismaximizescreen);
|
||||
setfullscreen(c->swallowedby, c->isfullscreen);
|
||||
setmaximizescreen(c->swallowedby, c->ismaximizescreen, true);
|
||||
setfullscreen(c->swallowedby, c->isfullscreen, true);
|
||||
c->swallowedby->swallowing = NULL;
|
||||
c->swallowedby = NULL;
|
||||
}
|
||||
|
|
@ -6825,16 +6844,17 @@ void virtualpointer(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
|
||||
#ifdef XWAYLAND
|
||||
void fix_xwayland_unmanaged_coordinate(Client *c) {
|
||||
void fix_xwayland_coordinate(struct wlr_box *geom) {
|
||||
if (!selmon)
|
||||
return;
|
||||
|
||||
// 1. 如果窗口已经在当前活动显示器内,直接返回
|
||||
if (c->geom.x >= selmon->m.x && c->geom.x < selmon->m.x + selmon->m.width &&
|
||||
c->geom.y >= selmon->m.y && c->geom.y < selmon->m.y + selmon->m.height)
|
||||
if (geom->x >= selmon->m.x && geom->x <= selmon->m.x + selmon->m.width &&
|
||||
geom->y >= selmon->m.y && geom->y <= selmon->m.y + selmon->m.height)
|
||||
return;
|
||||
|
||||
c->geom = setclient_coordinate_center(c, selmon, c->geom, 0, 0);
|
||||
geom->x = selmon->m.x + (selmon->m.width - geom->width) / 2;
|
||||
geom->y = selmon->m.y + (selmon->m.height - geom->height) / 2;
|
||||
}
|
||||
|
||||
int32_t synckeymap(void *data) {
|
||||
|
|
@ -6889,24 +6909,41 @@ void activatex11(struct wl_listener *listener, void *data) {
|
|||
void configurex11(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, configure);
|
||||
struct wlr_xwayland_surface_configure_event *event = data;
|
||||
struct wlr_box new_geo;
|
||||
new_geo.x = event->x;
|
||||
new_geo.y = event->y;
|
||||
new_geo.width = event->width;
|
||||
new_geo.height = event->height;
|
||||
fix_xwayland_coordinate(&new_geo);
|
||||
|
||||
if (!client_surface(c) || !client_surface(c)->mapped) {
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y,
|
||||
event->width, event->height);
|
||||
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, new_geo.x,
|
||||
new_geo.y, new_geo.width,
|
||||
new_geo.height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client_is_unmanaged(c)) {
|
||||
wlr_scene_node_set_position(&c->scene->node, event->x, event->y);
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, event->x, event->y,
|
||||
event->width, event->height);
|
||||
wlr_scene_node_set_position(&c->scene->node, new_geo.x, new_geo.y);
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, new_geo.x,
|
||||
new_geo.y, new_geo.width,
|
||||
new_geo.height);
|
||||
return;
|
||||
}
|
||||
if ((c->isfloating && c != grabc) ||
|
||||
!c->mon->pertag->ltidxs[c->mon->pertag->curtag]->arrange) {
|
||||
|
||||
if (c->isfloating && c != grabc) {
|
||||
new_geo.x = new_geo.x - c->bw;
|
||||
new_geo.y = new_geo.y - c->bw;
|
||||
new_geo.width = new_geo.width + c->bw * 2;
|
||||
new_geo.height = new_geo.height + c->bw * 2;
|
||||
fix_xwayland_coordinate(&new_geo);
|
||||
|
||||
resize(c,
|
||||
(struct wlr_box){.x = event->x - c->bw,
|
||||
.y = event->y - c->bw,
|
||||
.width = event->width + c->bw * 2,
|
||||
.height = event->height + c->bw * 2},
|
||||
(struct wlr_box){.x = new_geo.x,
|
||||
.y = new_geo.y,
|
||||
.width = new_geo.width,
|
||||
.height = new_geo.height},
|
||||
0);
|
||||
} else {
|
||||
arrange(c->mon, false, false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue