Merge branch 'main' into feature/dual-row-scroller

This commit is contained in:
2025-12-22 14:55:39 +01:00
20 changed files with 695 additions and 444 deletions

View File

@@ -32,7 +32,7 @@ Scroller Layout
https://github.com/user-attachments/assets/c9bf9415-fad1-4400-bcdc-3ad2d76de85a https://github.com/user-attachments/assets/c9bf9415-fad1-4400-bcdc-3ad2d76de85a
Layer animaiton Layer animation
https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0 https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0

View File

@@ -48,6 +48,8 @@ animation_curve_move=0.46,1.0,0.29,1
animation_curve_tag=0.46,1.0,0.29,1 animation_curve_tag=0.46,1.0,0.29,1
animation_curve_close=0.08,0.92,0,1 animation_curve_close=0.08,0.92,0,1
animation_curve_focus=0.46,1.0,0.29,1 animation_curve_focus=0.46,1.0,0.29,1
animation_curve_opafadeout=0.5,0.5,0.5,0.5
animation_curve_opafadein=0.46,1.0,0.29,1
# Scroller Layout Setting # Scroller Layout Setting
scroller_structs=20 scroller_structs=20
@@ -76,7 +78,7 @@ overviewgappo=30
no_border_when_single=0 no_border_when_single=0
axis_bind_apply_timeout=100 axis_bind_apply_timeout=100
focus_on_activate=1 focus_on_activate=1
inhibit_regardless_of_visibility=0 idleinhibit_ignore_visible=0
sloppyfocus=1 sloppyfocus=1
warpcursor=1 warpcursor=1
focus_cross_monitor=0 focus_cross_monitor=0

64
mangowc.scm Normal file
View File

@@ -0,0 +1,64 @@
(define-module (mangowc)
#:use-module (guix download)
#:use-module (guix git-download)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix utils)
#:use-module (gnu packages wm)
#:use-module (gnu packages freedesktop)
#:use-module (gnu packages xdisorg)
#:use-module (gnu packages pciutils)
#:use-module (gnu packages admin)
#:use-module (gnu packages pcre)
#:use-module (gnu packages xorg)
#:use-module (gnu packages build-tools)
#:use-module (gnu packages ninja)
#:use-module (gnu packages pkg-config)
#:use-module (guix build-system meson)
#:use-module (guix licenses))
(define-public mangowc-git
(package
(name "mangowc")
(version "git")
(source (local-file "." "mangowc-checkout"
#:recursive? #t
#:select? (or (git-predicate (current-source-directory))
(const #t))))
(build-system meson-build-system)
(arguments
(list
#:configure-flags
#~(list (string-append "-Dsysconfdir=" #$output "/etc"))
#:phases
#~(modify-phases %standard-phases
(add-before 'configure 'patch-meson
(lambda _
(substitute* "meson.build"
(("'-DSYSCONFDIR=\\\"@0@\\\"'.format\\('/etc'\\)")
"'-DSYSCONFDIR=\"@0@\"'.format(sysconfdir)")
(("sysconfdir = sysconfdir.substring\\(prefix.length\\(\\)\\)")
"")))))))
(inputs (list wayland
libinput
libdrm
libxkbcommon
pixman
libdisplay-info
libliftoff
hwdata
seatd
pcre2
libxcb
xcb-util-wm
wlroots
scenefx))
(native-inputs (list pkg-config wayland-protocols))
(home-page "https://github.com/DreamMaoMao/mangowc")
(synopsis "Wayland compositor based on wlroots and scenefx")
(description "A Wayland compositor based on wlroots and scenefx,
inspired by dwl but aiming to be more feature-rich.")
(license gpl3)))
mangowc-git

View File

@@ -1,5 +1,5 @@
project('mango', ['c', 'cpp'], project('mango', ['c', 'cpp'],
version : '0.10.7', version : '0.10.8',
) )
subdir('protocols') subdir('protocols')

View File

@@ -13,60 +13,64 @@
wayland-scanner, wayland-scanner,
xcbutilwm, xcbutilwm,
xwayland, xwayland,
enableXWayland ? true,
meson, meson,
ninja, ninja,
scenefx, scenefx,
wlroots_0_19, wlroots_0_19,
libGL, libGL,
}: let enableXWayland ? true,
debug ? false,
}:
stdenv.mkDerivation {
pname = "mango"; pname = "mango";
in version = "nightly";
stdenv.mkDerivation {
inherit pname;
version = "nightly";
src = builtins.path { src = builtins.path {
path = ../.; path = ../.;
name = "source"; name = "source";
}; };
nativeBuildInputs = [ mesonFlags = [
meson (lib.mesonEnable "xwayland" enableXWayland)
ninja (lib.mesonBool "asan" debug)
pkg-config ];
wayland-scanner
nativeBuildInputs = [
meson
ninja
pkg-config
wayland-scanner
];
buildInputs =
[
libinput
libxcb
libxkbcommon
pcre2
pixman
wayland
wayland-protocols
wlroots_0_19
scenefx
libGL
]
++ lib.optionals enableXWayland [
libX11
xcbutilwm
xwayland
]; ];
buildInputs = passthru = {
[ providedSessions = ["mango"];
libinput };
libxcb
libxkbcommon
pcre2
pixman
wayland
wayland-protocols
wlroots_0_19
scenefx
libGL
]
++ lib.optionals enableXWayland [
libX11
xcbutilwm
xwayland
];
passthru = { meta = {
providedSessions = ["mango"]; mainProgram = "mango";
}; description = "A streamlined but feature-rich Wayland compositor";
homepage = "https://github.com/DreamMaoMao/mango";
meta = { license = lib.licenses.gpl3Plus;
mainProgram = "mango"; maintainers = [];
description = "A streamlined but feature-rich Wayland compositor"; platforms = lib.platforms.unix;
homepage = "https://github.com/DreamMaoMao/mango"; };
license = lib.licenses.gpl3Plus; }
maintainers = [];
platforms = lib.platforms.unix;
};
}

View File

@@ -240,8 +240,9 @@ void buffer_set_effect(Client *c, BufferData data) {
if (c == grabc) if (c == grabc)
data.should_scale = false; data.should_scale = false;
if (c->isfullscreen || (no_radius_when_single && c->mon && if (c->isnoradius || c->isfullscreen ||
c->mon->visible_tiling_clients == 1)) { (no_radius_when_single && c->mon &&
c->mon->visible_tiling_clients == 1)) {
data.corner_location = CORNER_LOCATION_NONE; data.corner_location = CORNER_LOCATION_NONE;
} }
@@ -354,11 +355,13 @@ void apply_border(Client *c) {
return; return;
bool hit_no_border = check_hit_no_border(c); bool hit_no_border = check_hit_no_border(c);
enum corner_location current_corner_location = enum corner_location current_corner_location;
c->isfullscreen || (no_radius_when_single && c->mon && if (c->isfullscreen || (no_radius_when_single && c->mon &&
c->mon->visible_tiling_clients == 1) c->mon->visible_tiling_clients == 1)) {
? CORNER_LOCATION_NONE current_corner_location = CORNER_LOCATION_NONE;
: CORNER_LOCATION_ALL; } else {
current_corner_location = set_client_corner_location(c);
}
// Handle no-border cases // Handle no-border cases
if (hit_no_border && smartgaps) { if (hit_no_border && smartgaps) {
@@ -630,6 +633,7 @@ void fadeout_client_animation_next_tick(Client *c) {
int type = c->animation.action = c->animation.action; int type = c->animation.action = c->animation.action;
double factor = find_animation_curve_at(animation_passed, type); double factor = find_animation_curve_at(animation_passed, type);
uint32_t width = c->animation.initial.width + uint32_t width = c->animation.initial.width +
(c->current.width - c->animation.initial.width) * factor; (c->current.width - c->animation.initial.width) * factor;
uint32_t height = uint32_t height =
@@ -650,7 +654,13 @@ void fadeout_client_animation_next_tick(Client *c) {
.height = height, .height = height,
}; };
double opacity = MAX(fadeout_begin_opacity - animation_passed, 0); double opacity_eased_progress =
find_animation_curve_at(animation_passed, OPAFADEOUT);
double percent = fadeout_begin_opacity -
(opacity_eased_progress * fadeout_begin_opacity);
double opacity = MAX(percent, 0);
if (animation_fade_out && !c->nofadeout) if (animation_fade_out && !c->nofadeout)
wlr_scene_node_for_each_buffer(&c->scene->node, wlr_scene_node_for_each_buffer(&c->scene->node,
@@ -701,10 +711,10 @@ void client_animation_next_tick(Client *c) {
c->animation.initial.height + c->animation.initial.height +
(c->current.height - c->animation.initial.height) * factor; (c->current.height - c->animation.initial.height) * factor;
uint32_t x = c->animation.initial.x + int32_t x = c->animation.initial.x +
(c->current.x - c->animation.initial.x) * factor; (c->current.x - c->animation.initial.x) * factor;
uint32_t y = c->animation.initial.y + int32_t y = c->animation.initial.y +
(c->current.y - c->animation.initial.y) * factor; (c->current.y - c->animation.initial.y) * factor;
wlr_scene_node_set_position(&c->scene->node, x, y); wlr_scene_node_set_position(&c->scene->node, x, y);
c->animation.current = (struct wlr_box){ c->animation.current = (struct wlr_box){
@@ -1109,8 +1119,11 @@ bool client_apply_focus_opacity(Client *c) {
? (double)passed_time / (double)c->animation.duration ? (double)passed_time / (double)c->animation.duration
: 1.0; : 1.0;
double opacity_eased_progress =
find_animation_curve_at(linear_progress, OPAFADEIN);
float percent = float percent =
animation_fade_in && !c->nofadein ? linear_progress : 1.0; animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0;
float opacity = float opacity =
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity; c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;

View File

@@ -11,6 +11,10 @@ struct dvec2 calculate_animation_curve_at(double t, int type) {
animation_curve = animation_curve_close; animation_curve = animation_curve_close;
} else if (type == FOCUS) { } else if (type == FOCUS) {
animation_curve = animation_curve_focus; animation_curve = animation_curve_focus;
} else if (type == OPAFADEIN) {
animation_curve = animation_curve_opafadein;
} else if (type == OPAFADEOUT) {
animation_curve = animation_curve_opafadeout;
} else { } else {
animation_curve = animation_curve_move; animation_curve = animation_curve_move;
} }
@@ -32,6 +36,10 @@ void init_baked_points(void) {
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close)); calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close));
baked_points_focus = baked_points_focus =
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_focus)); calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_focus));
baked_points_opafadein =
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_opafadein));
baked_points_opafadeout =
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_opafadeout));
for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points_move[i] = calculate_animation_curve_at( baked_points_move[i] = calculate_animation_curve_at(
@@ -53,6 +61,14 @@ void init_baked_points(void) {
baked_points_focus[i] = calculate_animation_curve_at( baked_points_focus[i] = calculate_animation_curve_at(
(double)i / (BAKED_POINTS_COUNT - 1), FOCUS); (double)i / (BAKED_POINTS_COUNT - 1), FOCUS);
} }
for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points_opafadein[i] = calculate_animation_curve_at(
(double)i / (BAKED_POINTS_COUNT - 1), OPAFADEIN);
}
for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) {
baked_points_opafadeout[i] = calculate_animation_curve_at(
(double)i / (BAKED_POINTS_COUNT - 1), OPAFADEOUT);
}
} }
double find_animation_curve_at(double t, int type) { double find_animation_curve_at(double t, int type) {
@@ -71,6 +87,10 @@ double find_animation_curve_at(double t, int type) {
baked_points = baked_points_close; baked_points = baked_points_close;
} else if (type == FOCUS) { } else if (type == FOCUS) {
baked_points = baked_points_focus; baked_points = baked_points_focus;
} else if (type == OPAFADEIN) {
baked_points = baked_points_opafadein;
} else if (type == OPAFADEOUT) {
baked_points = baked_points_opafadeout;
} else { } else {
baked_points = baked_points_move; baked_points = baked_points_move;
} }

View File

@@ -276,7 +276,13 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
.height = height, .height = height,
}; };
double opacity = MAX(fadeout_begin_opacity - animation_passed, 0.0f); double opacity_eased_progress =
find_animation_curve_at(animation_passed, OPAFADEOUT);
double percent = fadeout_begin_opacity -
(opacity_eased_progress * fadeout_begin_opacity);
double opacity = MAX(percent, 0.0f);
if (animation_fade_out) if (animation_fade_out)
wlr_scene_node_for_each_buffer(&l->scene->node, wlr_scene_node_for_each_buffer(&l->scene->node,
@@ -318,9 +324,13 @@ void layer_animation_next_tick(LayerSurface *l) {
uint32_t y = l->animation.initial.y + uint32_t y = l->animation.initial.y +
(l->current.y - l->animation.initial.y) * factor; (l->current.y - l->animation.initial.y) * factor;
double opacity = MIN(fadein_begin_opacity + double opacity_eased_progress =
animation_passed * (1.0 - fadein_begin_opacity), find_animation_curve_at(animation_passed, OPAFADEIN);
1.0f);
double opacity =
MIN(fadein_begin_opacity +
opacity_eased_progress * (1.0 - fadein_begin_opacity),
1.0f);
if (animation_fade_in) if (animation_fade_in)
wlr_scene_node_for_each_buffer(&l->scene->node, wlr_scene_node_for_each_buffer(&l->scene->node,

View File

@@ -64,6 +64,7 @@ typedef struct {
const char *layer_animation_type_close; const char *layer_animation_type_close;
int isnoborder; int isnoborder;
int isnoshadow; int isnoshadow;
int isnoradius;
int isnoanimation; int isnoanimation;
int isopensilent; int isopensilent;
int istagsilent; int istagsilent;
@@ -194,6 +195,8 @@ typedef struct {
double animation_curve_tag[4]; double animation_curve_tag[4];
double animation_curve_close[4]; double animation_curve_close[4];
double animation_curve_focus[4]; double animation_curve_focus[4];
double animation_curve_opafadein[4];
double animation_curve_opafadeout[4];
int scroller_structs; int scroller_structs;
float scroller_default_proportion; float scroller_default_proportion;
@@ -237,7 +240,7 @@ typedef struct {
uint32_t axis_bind_apply_timeout; uint32_t axis_bind_apply_timeout;
uint32_t focus_on_activate; uint32_t focus_on_activate;
int inhibit_regardless_of_visibility; int idleinhibit_ignore_visible;
int sloppyfocus; int sloppyfocus;
int warpcursor; int warpcursor;
@@ -264,6 +267,8 @@ typedef struct {
uint32_t send_events_mode; uint32_t send_events_mode;
uint32_t button_map; uint32_t button_map;
double axis_scroll_factor;
int blur; int blur;
int blur_layer; int blur_layer;
int blur_optimized; int blur_optimized;
@@ -1187,6 +1192,22 @@ void parse_option(Config *config, char *key, char *value) {
"Error: Failed to parse animation_curve_focus: %s\n", "Error: Failed to parse animation_curve_focus: %s\n",
value); value);
} }
} else if (strcmp(key, "animation_curve_opafadein") == 0) {
int num =
parse_double_array(value, config->animation_curve_opafadein, 4);
if (num != 4) {
fprintf(stderr,
"Error: Failed to parse animation_curve_opafadein: %s\n",
value);
}
} else if (strcmp(key, "animation_curve_opafadeout") == 0) {
int num =
parse_double_array(value, config->animation_curve_opafadeout, 4);
if (num != 4) {
fprintf(stderr,
"Error: Failed to parse animation_curve_opafadeout: %s\n",
value);
}
} else if (strcmp(key, "scroller_structs") == 0) { } else if (strcmp(key, "scroller_structs") == 0) {
config->scroller_structs = atoi(value); config->scroller_structs = atoi(value);
} else if (strcmp(key, "scroller_default_proportion") == 0) { } else if (strcmp(key, "scroller_default_proportion") == 0) {
@@ -1446,8 +1467,8 @@ void parse_option(Config *config, char *key, char *value) {
config->focus_on_activate = atoi(value); config->focus_on_activate = atoi(value);
} else if (strcmp(key, "numlockon") == 0) { } else if (strcmp(key, "numlockon") == 0) {
config->numlockon = atoi(value); config->numlockon = atoi(value);
} else if (strcmp(key, "inhibit_regardless_of_visibility") == 0) { } else if (strcmp(key, "idleinhibit_ignore_visible") == 0) {
config->inhibit_regardless_of_visibility = atoi(value); config->idleinhibit_ignore_visible = atoi(value);
} else if (strcmp(key, "sloppyfocus") == 0) { } else if (strcmp(key, "sloppyfocus") == 0) {
config->sloppyfocus = atoi(value); config->sloppyfocus = atoi(value);
} else if (strcmp(key, "warpcursor") == 0) { } else if (strcmp(key, "warpcursor") == 0) {
@@ -1494,6 +1515,8 @@ void parse_option(Config *config, char *key, char *value) {
config->send_events_mode = atoi(value); config->send_events_mode = atoi(value);
} else if (strcmp(key, "button_map") == 0) { } else if (strcmp(key, "button_map") == 0) {
config->button_map = atoi(value); config->button_map = atoi(value);
} else if (strcmp(key, "axis_scroll_factor") == 0) {
config->axis_scroll_factor = atof(value);
} else if (strcmp(key, "gappih") == 0) { } else if (strcmp(key, "gappih") == 0) {
config->gappih = atoi(value); config->gappih = atoi(value);
} else if (strcmp(key, "gappiv") == 0) { } else if (strcmp(key, "gappiv") == 0) {
@@ -1691,6 +1714,7 @@ void parse_option(Config *config, char *key, char *value) {
rule->isfullscreen = -1; rule->isfullscreen = -1;
rule->isnoborder = -1; rule->isnoborder = -1;
rule->isnoshadow = -1; rule->isnoshadow = -1;
rule->isnoradius = -1;
rule->isnoanimation = -1; rule->isnoanimation = -1;
rule->isopensilent = -1; rule->isopensilent = -1;
rule->istagsilent = -1; rule->istagsilent = -1;
@@ -1780,6 +1804,8 @@ void parse_option(Config *config, char *key, char *value) {
rule->isnoborder = atoi(val); rule->isnoborder = atoi(val);
} else if (strcmp(key, "isnoshadow") == 0) { } else if (strcmp(key, "isnoshadow") == 0) {
rule->isnoshadow = atoi(val); rule->isnoshadow = atoi(val);
} else if (strcmp(key, "isnoradius") == 0) {
rule->isnoradius = atoi(val);
} else if (strcmp(key, "isnoanimation") == 0) { } else if (strcmp(key, "isnoanimation") == 0) {
rule->isnoanimation = atoi(val); rule->isnoanimation = atoi(val);
} else if (strcmp(key, "isopensilent") == 0) { } else if (strcmp(key, "isopensilent") == 0) {
@@ -2406,6 +2432,14 @@ void free_baked_points(void) {
free(baked_points_focus); free(baked_points_focus);
baked_points_focus = NULL; baked_points_focus = NULL;
} }
if (baked_points_opafadein) {
free(baked_points_opafadein);
baked_points_opafadein = NULL;
}
if (baked_points_opafadeout) {
free(baked_points_opafadeout);
baked_points_opafadeout = NULL;
}
} }
void free_config(void) { void free_config(void) {
@@ -2719,8 +2753,8 @@ void override_config(void) {
axis_bind_apply_timeout = axis_bind_apply_timeout =
CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000); CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000);
focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1); focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1);
inhibit_regardless_of_visibility = idleinhibit_ignore_visible =
CLAMP_INT(config.inhibit_regardless_of_visibility, 0, 1); CLAMP_INT(config.idleinhibit_ignore_visible, 0, 1);
sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1); sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1);
warpcursor = CLAMP_INT(config.warpcursor, 0, 1); warpcursor = CLAMP_INT(config.warpcursor, 0, 1);
focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1); focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1);
@@ -2764,6 +2798,7 @@ void override_config(void) {
click_method = CLAMP_INT(config.click_method, 0, 2); click_method = CLAMP_INT(config.click_method, 0, 2);
send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2); send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2);
button_map = CLAMP_INT(config.button_map, 0, 1); button_map = CLAMP_INT(config.button_map, 0, 1);
axis_scroll_factor = CLAMP_FLOAT(config.axis_scroll_factor, 0.1f, 10.0f);
// 外观设置 // 外观设置
gappih = CLAMP_INT(config.gappih, 0, 1000); gappih = CLAMP_INT(config.gappih, 0, 1000);
@@ -2820,6 +2855,10 @@ void override_config(void) {
sizeof(animation_curve_close)); sizeof(animation_curve_close));
memcpy(animation_curve_focus, config.animation_curve_focus, memcpy(animation_curve_focus, config.animation_curve_focus,
sizeof(animation_curve_focus)); sizeof(animation_curve_focus));
memcpy(animation_curve_opafadein, config.animation_curve_opafadein,
sizeof(animation_curve_opafadein));
memcpy(animation_curve_opafadeout, config.animation_curve_opafadeout,
sizeof(animation_curve_opafadeout));
} }
void set_value_default() { void set_value_default() {
@@ -2888,6 +2927,7 @@ void set_value_default() {
config.exchange_cross_monitor = exchange_cross_monitor; config.exchange_cross_monitor = exchange_cross_monitor;
config.scratchpad_cross_monitor = scratchpad_cross_monitor; config.scratchpad_cross_monitor = scratchpad_cross_monitor;
config.focus_cross_tag = focus_cross_tag; config.focus_cross_tag = focus_cross_tag;
config.axis_scroll_factor = axis_scroll_factor;
config.view_current_to_back = view_current_to_back; config.view_current_to_back = view_current_to_back;
config.single_scratchpad = single_scratchpad; config.single_scratchpad = single_scratchpad;
config.xwayland_persistence = xwayland_persistence; config.xwayland_persistence = xwayland_persistence;
@@ -2903,8 +2943,8 @@ void set_value_default() {
config.enable_floating_snap = enable_floating_snap; config.enable_floating_snap = enable_floating_snap;
config.swipe_min_threshold = swipe_min_threshold; config.swipe_min_threshold = swipe_min_threshold;
config.inhibit_regardless_of_visibility = config.idleinhibit_ignore_visible =
inhibit_regardless_of_visibility; /* 1 means idle inhibitors will idleinhibit_ignore_visible; /* 1 means idle inhibitors will
disable idle tracking even if it's disable idle tracking even if it's
surface isn't visible surface isn't visible
*/ */
@@ -2969,6 +3009,10 @@ void set_value_default() {
sizeof(animation_curve_close)); sizeof(animation_curve_close));
memcpy(config.animation_curve_focus, animation_curve_focus, memcpy(config.animation_curve_focus, animation_curve_focus,
sizeof(animation_curve_focus)); sizeof(animation_curve_focus));
memcpy(config.animation_curve_opafadein, animation_curve_opafadein,
sizeof(animation_curve_opafadein));
memcpy(config.animation_curve_opafadeout, animation_curve_opafadeout,
sizeof(animation_curve_opafadeout));
memcpy(config.rootcolor, rootcolor, sizeof(rootcolor)); memcpy(config.rootcolor, rootcolor, sizeof(rootcolor));
memcpy(config.bordercolor, bordercolor, sizeof(bordercolor)); memcpy(config.bordercolor, bordercolor, sizeof(bordercolor));
@@ -3171,9 +3215,37 @@ void reapply_monitor_rules(void) {
} }
void reapply_cursor_style(void) { void reapply_cursor_style(void) {
if (cursor_mgr) if (hide_source) {
wl_event_source_timer_update(hide_source, 0);
wl_event_source_remove(hide_source);
hide_source = NULL;
}
wlr_cursor_unset_image(cursor);
wlr_cursor_set_surface(cursor, NULL, 0, 0);
if (cursor_mgr) {
wlr_xcursor_manager_destroy(cursor_mgr); wlr_xcursor_manager_destroy(cursor_mgr);
cursor_mgr = NULL;
}
cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size); cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size);
Monitor *m = NULL;
wl_list_for_each(m, &mons, link) {
wlr_xcursor_manager_load(cursor_mgr, m->wlr_output->scale);
}
wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr");
hide_source = wl_event_loop_add_timer(wl_display_get_event_loop(dpy),
hidecursor, cursor);
if (cursor_hidden) {
wlr_cursor_unset_image(cursor);
} else {
wl_event_source_timer_update(hide_source, cursor_hide_timeout * 1000);
}
} }
void reapply_border(void) { void reapply_border(void) {
@@ -3293,5 +3365,5 @@ int reload_config(const Arg *arg) {
parse_config(); parse_config();
reset_option(); reset_option();
printstatus(); printstatus();
return 0; return 1;
} }

View File

@@ -26,11 +26,13 @@ uint32_t animation_duration_open = 400; // Animation open speed
uint32_t animation_duration_tag = 300; // Animation tag speed uint32_t animation_duration_tag = 300; // Animation tag speed
uint32_t animation_duration_close = 300; // Animation close speed uint32_t animation_duration_close = 300; // Animation close speed
uint32_t animation_duration_focus = 0; // Animation focus opacity speed uint32_t animation_duration_focus = 0; // Animation focus opacity speed
double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_close[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_close[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_focus[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_focus[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_opafadein[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线
double animation_curve_opafadeout[4] = {0.5, 0.5, 0.5, 0.5}; // 动画曲线
/* appearance */ /* appearance */
uint32_t axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔 uint32_t axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔
@@ -79,7 +81,7 @@ uint32_t cursor_hide_timeout = 0;
uint32_t swipe_min_threshold = 1; uint32_t swipe_min_threshold = 1;
int inhibit_regardless_of_visibility = int idleinhibit_ignore_visible =
0; /* 1 means idle inhibitors will disable idle tracking even if it's 0; /* 1 means idle inhibitors will disable idle tracking even if it's
surface isn't visible */ surface isn't visible */
uint32_t borderpx = 4; /* border pixel of windows */ uint32_t borderpx = 4; /* border pixel of windows */
@@ -105,7 +107,7 @@ int xwayland_persistence = 1; /* xwayland persistence */
int syncobj_enable = 0; int syncobj_enable = 0;
int adaptive_sync = 0; int adaptive_sync = 0;
int allow_lock_transparent = 0; int allow_lock_transparent = 0;
double drag_refresh_interval = 30.0; double drag_refresh_interval = 16.0;
int allow_tearing = TEARING_DISABLED; int allow_tearing = TEARING_DISABLED;
int allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; int allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
@@ -177,6 +179,8 @@ LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
enum libinput_config_click_method click_method = enum libinput_config_click_method click_method =
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
double axis_scroll_factor = 1.0;
/* You can choose between: /* You can choose between:
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED LIBINPUT_CONFIG_SEND_EVENTS_DISABLED

View File

@@ -196,15 +196,17 @@ int toggle_trackpad_enable(const Arg *arg) {
int focusmon(const Arg *arg) { int focusmon(const Arg *arg) {
Client *c = NULL; Client *c = NULL;
Monitor *m = NULL; Monitor *m = NULL;
Monitor *tm = NULL;
if (arg->i != UNDIR) { if (arg->i != UNDIR) {
m = dirtomon(arg->i); tm = dirtomon(arg->i);
} else if (arg->v) { } else if (arg->v) {
wl_list_for_each(m, &mons, link) { wl_list_for_each(m, &mons, link) {
if (!m->wlr_output->enabled) { if (!m->wlr_output->enabled) {
continue; continue;
} }
if (regex_match(arg->v, m->wlr_output->name)) { if (regex_match(arg->v, m->wlr_output->name)) {
tm = m;
break; break;
} }
} }
@@ -212,10 +214,10 @@ int focusmon(const Arg *arg) {
return 0; return 0;
} }
if (!m || !m->wlr_output->enabled || m == selmon) if (!tm || !tm->wlr_output->enabled || tm == selmon)
return 0; return 0;
selmon = m; selmon = tm;
if (warpcursor) { if (warpcursor) {
warp_cursor_to_selmon(selmon); warp_cursor_to_selmon(selmon);
} }

View File

@@ -1,8 +1,8 @@
#include "wlr_ext_workspace_v1.h" #include "wlr_ext_workspace_v1.h"
#define EXT_WORKSPACE_ENABLE_CAPS \ #define EXT_WORKSPACE_ENABLE_CAPS \
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ACTIVATE | \ EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE | \
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_DEACTIVATE EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_DEACTIVATE
typedef struct Monitor Monitor; typedef struct Monitor Monitor;

View File

@@ -29,7 +29,7 @@ struct wlr_ext_workspace_v1_request {
// ACTIVATE / DEACTIVATE / ASSIGN / REMOVE // ACTIVATE / DEACTIVATE / ASSIGN / REMOVE
struct wlr_ext_workspace_handle_v1 *workspace; struct wlr_ext_workspace_handle_v1 *workspace;
struct wl_list link; // wlr_ext_workspace_manager_client_v1.requests struct wl_list link; // wlr_ext_workspace_manager_v1_resource.requests
}; };
struct wlr_ext_workspace_v1_group_output { struct wlr_ext_workspace_v1_group_output {
@@ -41,33 +41,40 @@ struct wlr_ext_workspace_v1_group_output {
}; };
// These structs wrap wl_resource of each interface to access the request queue // These structs wrap wl_resource of each interface to access the request queue
// (wlr_ext_workspace_manager_client_v1.requests) assigned per manager resource // (wlr_ext_workspace_manager_v1_resource.requests) assigned per manager
// resource
struct wlr_ext_workspace_manager_client_v1 { struct wlr_ext_workspace_manager_v1_resource {
struct wl_resource *resource; struct wl_resource *resource;
struct wlr_ext_workspace_manager_v1 *manager; struct wlr_ext_workspace_manager_v1 *manager;
struct wl_list requests; // wlr_ext_workspace_v1_request.link struct wl_list requests; // wlr_ext_workspace_v1_request.link
struct wl_list link; // wlr_ext_workspace_manager_v1.clients struct wl_list workspace_resources; // wlr_ext_workspace_v1_resource.link
struct wl_list group_resources; // wlr_ext_workspace_group_v1_resource.link
struct wl_list link; // wlr_ext_workspace_manager_v1.resources
}; };
struct wlr_ext_workspace_group_client_v1 { struct wlr_ext_workspace_group_v1_resource {
struct wl_resource *resource; struct wl_resource *resource;
struct wlr_ext_workspace_group_handle_v1 *group; struct wlr_ext_workspace_group_handle_v1 *group;
struct wlr_ext_workspace_manager_client_v1 *manager; struct wlr_ext_workspace_manager_v1_resource *manager;
struct wl_list link; // wlr_ext_workspace_group_v1.clients struct wl_list link; // wlr_ext_workspace_group_v1.resources
struct wl_list
manager_resource_link; // wlr_ext_workspace_manager_v1_resource.group_resources
}; };
struct wlr_ext_workspace_client_v1 { struct wlr_ext_workspace_v1_resource {
struct wl_resource *resource; struct wl_resource *resource;
struct wlr_ext_workspace_handle_v1 *workspace; struct wlr_ext_workspace_handle_v1 *workspace;
struct wlr_ext_workspace_manager_client_v1 *manager; struct wlr_ext_workspace_manager_v1_resource *manager;
struct wl_list link; // wlr_ext_workspace_v1.clients struct wl_list link; // wlr_ext_workspace_v1.resources
struct wl_list
manager_resource_link; // wlr_ext_workspace_manager_v1_resource.workspace_resources
}; };
static const struct ext_workspace_group_handle_v1_interface group_impl; static const struct ext_workspace_group_handle_v1_interface group_impl;
static struct wlr_ext_workspace_group_client_v1 * static struct wlr_ext_workspace_group_v1_resource *
group_client_from_resource(struct wl_resource *resource) { group_resource_from_resource(struct wl_resource *resource) {
assert(wl_resource_instance_of( assert(wl_resource_instance_of(
resource, &ext_workspace_group_handle_v1_interface, &group_impl)); resource, &ext_workspace_group_handle_v1_interface, &group_impl));
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
@@ -75,8 +82,8 @@ group_client_from_resource(struct wl_resource *resource) {
static const struct ext_workspace_handle_v1_interface workspace_impl; static const struct ext_workspace_handle_v1_interface workspace_impl;
static struct wlr_ext_workspace_client_v1 * static struct wlr_ext_workspace_v1_resource *
workspace_client_from_resource(struct wl_resource *resource) { workspace_resource_from_resource(struct wl_resource *resource) {
assert(wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface, assert(wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface,
&workspace_impl)); &workspace_impl));
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
@@ -84,8 +91,8 @@ workspace_client_from_resource(struct wl_resource *resource) {
static const struct ext_workspace_manager_v1_interface manager_impl; static const struct ext_workspace_manager_v1_interface manager_impl;
static struct wlr_ext_workspace_manager_client_v1 * static struct wlr_ext_workspace_manager_v1_resource *
manager_client_from_resource(struct wl_resource *resource) { manager_resource_from_resource(struct wl_resource *resource) {
assert(wl_resource_instance_of( assert(wl_resource_instance_of(
resource, &ext_workspace_manager_v1_interface, &manager_impl)); resource, &ext_workspace_manager_v1_interface, &manager_impl));
return wl_resource_get_user_data(resource); return wl_resource_get_user_data(resource);
@@ -98,9 +105,9 @@ static void workspace_handle_destroy(struct wl_client *client,
static void workspace_handle_activate(struct wl_client *client, static void workspace_handle_activate(struct wl_client *client,
struct wl_resource *workspace_resource) { struct wl_resource *workspace_resource) {
struct wlr_ext_workspace_client_v1 *workspace = struct wlr_ext_workspace_v1_resource *workspace_res =
workspace_client_from_resource(workspace_resource); workspace_resource_from_resource(workspace_resource);
if (!workspace) { if (!workspace_res) {
return; return;
} }
@@ -110,16 +117,16 @@ static void workspace_handle_activate(struct wl_client *client,
return; return;
} }
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE; req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE;
req->workspace = workspace->workspace; req->workspace = workspace_res->workspace;
wl_list_insert(workspace->manager->requests.prev, &req->link); wl_list_insert(workspace_res->manager->requests.prev, &req->link);
} }
static void static void
workspace_handle_deactivate(struct wl_client *client, workspace_handle_deactivate(struct wl_client *client,
struct wl_resource *workspace_resource) { struct wl_resource *workspace_resource) {
struct wlr_ext_workspace_client_v1 *workspace = struct wlr_ext_workspace_v1_resource *workspace_res =
workspace_client_from_resource(workspace_resource); workspace_resource_from_resource(workspace_resource);
if (!workspace) { if (!workspace_res) {
return; return;
} }
@@ -129,18 +136,18 @@ workspace_handle_deactivate(struct wl_client *client,
return; return;
} }
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE; req->type = WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE;
req->workspace = workspace->workspace; req->workspace = workspace_res->workspace;
wl_list_insert(workspace->manager->requests.prev, &req->link); wl_list_insert(workspace_res->manager->requests.prev, &req->link);
} }
static void workspace_handle_assign(struct wl_client *client, static void workspace_handle_assign(struct wl_client *client,
struct wl_resource *workspace_resource, struct wl_resource *workspace_resource,
struct wl_resource *group_resource) { struct wl_resource *group_resource) {
struct wlr_ext_workspace_client_v1 *workspace = struct wlr_ext_workspace_v1_resource *workspace_res =
workspace_client_from_resource(workspace_resource); workspace_resource_from_resource(workspace_resource);
struct wlr_ext_workspace_group_client_v1 *group = struct wlr_ext_workspace_group_v1_resource *group_res =
group_client_from_resource(group_resource); group_resource_from_resource(group_resource);
if (!workspace || !group) { if (!workspace_res || !group_res) {
return; return;
} }
@@ -150,16 +157,16 @@ static void workspace_handle_assign(struct wl_client *client,
return; return;
} }
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN; req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN;
req->group = group->group; req->group = group_res->group;
req->workspace = workspace->workspace; req->workspace = workspace_res->workspace;
wl_list_insert(workspace->manager->requests.prev, &req->link); wl_list_insert(workspace_res->manager->requests.prev, &req->link);
} }
static void workspace_handle_remove(struct wl_client *client, static void workspace_handle_remove(struct wl_client *client,
struct wl_resource *workspace_resource) { struct wl_resource *workspace_resource) {
struct wlr_ext_workspace_client_v1 *workspace = struct wlr_ext_workspace_v1_resource *workspace_res =
workspace_client_from_resource(workspace_resource); workspace_resource_from_resource(workspace_resource);
if (!workspace) { if (!workspace_res) {
return; return;
} }
@@ -169,8 +176,8 @@ static void workspace_handle_remove(struct wl_client *client,
return; return;
} }
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE; req->type = WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE;
req->workspace = workspace->workspace; req->workspace = workspace_res->workspace;
wl_list_insert(workspace->manager->requests.prev, &req->link); wl_list_insert(workspace_res->manager->requests.prev, &req->link);
} }
static const struct ext_workspace_handle_v1_interface workspace_impl = { static const struct ext_workspace_handle_v1_interface workspace_impl = {
@@ -184,9 +191,9 @@ static const struct ext_workspace_handle_v1_interface workspace_impl = {
static void group_handle_create_workspace(struct wl_client *client, static void group_handle_create_workspace(struct wl_client *client,
struct wl_resource *group_resource, struct wl_resource *group_resource,
const char *name) { const char *name) {
struct wlr_ext_workspace_group_client_v1 *group = struct wlr_ext_workspace_group_v1_resource *group_res =
group_client_from_resource(group_resource); group_resource_from_resource(group_resource);
if (!group) { if (!group_res) {
return; return;
} }
@@ -195,9 +202,15 @@ static void group_handle_create_workspace(struct wl_client *client,
wl_resource_post_no_memory(group_resource); wl_resource_post_no_memory(group_resource);
return; return;
} }
req->name = strdup(name);
if (!req->name) {
free(req);
wl_resource_post_no_memory(group_resource);
return;
}
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE; req->type = WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE;
req->group = group->group; req->group = group_res->group;
wl_list_insert(group->manager->requests.prev, &req->link); wl_list_insert(group_res->manager->requests.prev, &req->link);
} }
static void group_handle_destroy(struct wl_client *client, static void group_handle_destroy(struct wl_client *client,
@@ -210,89 +223,94 @@ static const struct ext_workspace_group_handle_v1_interface group_impl = {
.destroy = group_handle_destroy, .destroy = group_handle_destroy,
}; };
static void static void destroy_workspace_resource(
destroy_workspace_client(struct wlr_ext_workspace_client_v1 *workspace_client) { struct wlr_ext_workspace_v1_resource *workspace_res) {
wl_list_remove(&workspace_client->link); wl_list_remove(&workspace_res->link);
wl_resource_set_user_data(workspace_client->resource, NULL); wl_list_remove(&workspace_res->manager_resource_link);
free(workspace_client); wl_resource_set_user_data(workspace_res->resource, NULL);
free(workspace_res);
} }
static void workspace_resource_destroy(struct wl_resource *resource) { static void workspace_resource_destroy(struct wl_resource *resource) {
struct wlr_ext_workspace_client_v1 *workspace_client = struct wlr_ext_workspace_v1_resource *workspace_res =
workspace_client_from_resource(resource); workspace_resource_from_resource(resource);
if (workspace_client) { if (workspace_res) {
destroy_workspace_client(workspace_client); destroy_workspace_resource(workspace_res);
} }
} }
static struct wlr_ext_workspace_client_v1 *create_workspace_client( static struct wlr_ext_workspace_v1_resource *create_workspace_resource(
struct wlr_ext_workspace_handle_v1 *workspace, struct wlr_ext_workspace_handle_v1 *workspace,
struct wlr_ext_workspace_manager_client_v1 *manager_client) { struct wlr_ext_workspace_manager_v1_resource *manager_res) {
struct wlr_ext_workspace_client_v1 *workspace_client = struct wlr_ext_workspace_v1_resource *workspace_res =
calloc(1, sizeof(*workspace_client)); calloc(1, sizeof(*workspace_res));
if (!workspace_client) { if (!workspace_res) {
return NULL; return NULL;
} }
struct wl_client *client = wl_resource_get_client(manager_client->resource); struct wl_client *client = wl_resource_get_client(manager_res->resource);
workspace_client->resource = wl_resource_create( workspace_res->resource =
client, &ext_workspace_handle_v1_interface, wl_resource_create(client, &ext_workspace_handle_v1_interface,
wl_resource_get_version(manager_client->resource), 0); wl_resource_get_version(manager_res->resource), 0);
if (!workspace_client->resource) { if (!workspace_res->resource) {
free(workspace_client); free(workspace_res);
return NULL; return NULL;
} }
wl_resource_set_implementation(workspace_client->resource, &workspace_impl, wl_resource_set_implementation(workspace_res->resource, &workspace_impl,
workspace_client, workspace_res, workspace_resource_destroy);
workspace_resource_destroy);
workspace_client->workspace = workspace; workspace_res->workspace = workspace;
workspace_client->manager = manager_client; workspace_res->manager = manager_res;
wl_list_insert(&workspace->clients, &workspace_client->link); wl_list_insert(&workspace->resources, &workspace_res->link);
wl_list_insert(&manager_res->workspace_resources,
&workspace_res->manager_resource_link);
return workspace_client; return workspace_res;
} }
static void static void
destroy_group_client(struct wlr_ext_workspace_group_client_v1 *group_client) { destroy_group_resource(struct wlr_ext_workspace_group_v1_resource *group_res) {
wl_list_remove(&group_client->link); wl_list_remove(&group_res->link);
wl_resource_set_user_data(group_client->resource, NULL); wl_list_remove(&group_res->manager_resource_link);
free(group_client); wl_resource_set_user_data(group_res->resource, NULL);
free(group_res);
} }
static void group_handle_resource_destroy(struct wl_resource *resource) { static void group_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_ext_workspace_group_client_v1 *group_client = struct wlr_ext_workspace_group_v1_resource *group_res =
group_client_from_resource(resource); group_resource_from_resource(resource);
if (group_client) { if (group_res) {
destroy_group_client(group_client); destroy_group_resource(group_res);
} }
} }
static struct wlr_ext_workspace_group_client_v1 *create_group_client( static struct wlr_ext_workspace_group_v1_resource *create_group_resource(
struct wlr_ext_workspace_group_handle_v1 *group, struct wlr_ext_workspace_group_handle_v1 *group,
struct wlr_ext_workspace_manager_client_v1 *manager_client) { struct wlr_ext_workspace_manager_v1_resource *manager_res) {
struct wlr_ext_workspace_group_client_v1 *group_client = struct wlr_ext_workspace_group_v1_resource *group_res =
calloc(1, sizeof(*group_client)); calloc(1, sizeof(*group_res));
if (!group_client) { if (!group_res) {
return NULL; return NULL;
} }
struct wl_client *client = wl_resource_get_client(manager_client->resource); struct wl_client *client = wl_resource_get_client(manager_res->resource);
uint32_t version = wl_resource_get_version(manager_client->resource); uint32_t version = wl_resource_get_version(manager_res->resource);
group_client->resource = wl_resource_create( group_res->resource = wl_resource_create(
client, &ext_workspace_group_handle_v1_interface, version, 0); client, &ext_workspace_group_handle_v1_interface, version, 0);
if (group_client->resource == NULL) { if (group_res->resource == NULL) {
free(group_client); free(group_res);
return NULL; return NULL;
} }
wl_resource_set_implementation(group_client->resource, &group_impl, wl_resource_set_implementation(group_res->resource, &group_impl, group_res,
group_client, group_handle_resource_destroy); group_handle_resource_destroy);
group_client->group = group; group_res->group = group;
group_client->manager = manager_client; group_res->manager = manager_res;
wl_list_insert(&group->clients, &group_client->link); wl_list_insert(&group->resources, &group_res->link);
wl_list_insert(&manager_res->group_resources,
&group_res->manager_resource_link);
return group_client; return group_res;
} }
static void destroy_request(struct wlr_ext_workspace_v1_request *req) { static void destroy_request(struct wlr_ext_workspace_v1_request *req) {
@@ -303,18 +321,22 @@ static void destroy_request(struct wlr_ext_workspace_v1_request *req) {
static void manager_handle_commit(struct wl_client *client, static void manager_handle_commit(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
struct wlr_ext_workspace_manager_client_v1 *manager = struct wlr_ext_workspace_manager_v1_resource *manager_res =
manager_client_from_resource(resource); manager_resource_from_resource(resource);
if (!manager) { if (!manager_res) {
return; return;
} }
struct wlr_ext_workspace_v1_request *req, *tmp; struct wlr_ext_workspace_v1_request *req, *tmp;
wl_list_for_each_safe(req, tmp, &manager->requests, link) { wl_list_for_each_safe(req, tmp, &manager_res->requests, link) {
switch (req->type) { switch (req->type) {
case WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE: case WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE:;
struct wlr_ext_workspace_group_handle_v1_create_workspace_event
event = {
.name = req->name,
};
wl_signal_emit_mutable(&req->group->events.create_workspace, wl_signal_emit_mutable(&req->group->events.create_workspace,
req->name); &event);
break; break;
case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE: case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE:
wl_signal_emit_mutable(&req->workspace->events.activate, NULL); wl_signal_emit_mutable(&req->workspace->events.activate, NULL);
@@ -323,13 +345,11 @@ static void manager_handle_commit(struct wl_client *client,
wl_signal_emit_mutable(&req->workspace->events.deactivate, NULL); wl_signal_emit_mutable(&req->workspace->events.deactivate, NULL);
break; break;
case WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN: case WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN:
wl_signal_emit_mutable(&req->workspace->events.assign, &req->group); wl_signal_emit_mutable(&req->workspace->events.assign, req->group);
break; break;
case WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE: case WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE:
wl_signal_emit_mutable(&req->workspace->events.remove, NULL); wl_signal_emit_mutable(&req->workspace->events.remove, NULL);
break; break;
default:
abort();
} }
destroy_request(req); destroy_request(req);
} }
@@ -338,9 +358,9 @@ static void manager_handle_commit(struct wl_client *client,
static void handle_idle(void *data) { static void handle_idle(void *data) {
struct wlr_ext_workspace_manager_v1 *manager = data; struct wlr_ext_workspace_manager_v1 *manager = data;
struct wlr_ext_workspace_manager_client_v1 *manager_client; struct wlr_ext_workspace_manager_v1_resource *manager_res;
wl_list_for_each(manager_client, &manager->clients, link) { wl_list_for_each(manager_res, &manager->resources, link) {
ext_workspace_manager_v1_send_done(manager_client->resource); ext_workspace_manager_v1_send_done(manager_res->resource);
} }
manager->idle_source = NULL; manager->idle_source = NULL;
} }
@@ -354,9 +374,9 @@ manager_schedule_done(struct wlr_ext_workspace_manager_v1 *manager) {
} }
static void static void
workspace_send_details(struct wlr_ext_workspace_client_v1 *workspace_client) { workspace_send_details(struct wlr_ext_workspace_v1_resource *workspace_res) {
struct wlr_ext_workspace_handle_v1 *workspace = workspace_client->workspace; struct wlr_ext_workspace_handle_v1 *workspace = workspace_res->workspace;
struct wl_resource *resource = workspace_client->resource; struct wl_resource *resource = workspace_res->resource;
ext_workspace_handle_v1_send_capabilities(resource, workspace->caps); ext_workspace_handle_v1_send_capabilities(resource, workspace->caps);
if (workspace->coordinates.size > 0) { if (workspace->coordinates.size > 0) {
@@ -384,29 +404,41 @@ static const struct ext_workspace_manager_v1_interface manager_impl = {
.stop = manager_handle_stop, .stop = manager_handle_stop,
}; };
static void destroy_manager_client( static void destroy_manager_resource(
struct wlr_ext_workspace_manager_client_v1 *manager_client) { struct wlr_ext_workspace_manager_v1_resource *manager_res) {
struct wlr_ext_workspace_v1_request *req, *tmp; struct wlr_ext_workspace_v1_request *req, *tmp;
wl_list_for_each_safe(req, tmp, &manager_client->requests, link) { wl_list_for_each_safe(req, tmp, &manager_res->requests, link) {
destroy_request(req); destroy_request(req);
} }
wl_list_remove(&manager_client->link); struct wlr_ext_workspace_v1_resource *workspace_res, *tmp2;
wl_resource_set_user_data(manager_client->resource, NULL); wl_list_for_each_safe(workspace_res, tmp2,
free(manager_client); &manager_res->workspace_resources,
manager_resource_link) {
destroy_workspace_resource(workspace_res);
}
struct wlr_ext_workspace_group_v1_resource *group_res, *tmp3;
wl_list_for_each_safe(group_res, tmp3, &manager_res->group_resources,
manager_resource_link) {
destroy_group_resource(group_res);
}
wl_list_remove(&manager_res->link);
wl_resource_set_user_data(manager_res->resource, NULL);
free(manager_res);
} }
static void manager_resource_destroy(struct wl_resource *resource) { static void manager_resource_destroy(struct wl_resource *resource) {
struct wlr_ext_workspace_manager_client_v1 *manager_client = struct wlr_ext_workspace_manager_v1_resource *manager_res =
manager_client_from_resource(resource); manager_resource_from_resource(resource);
if (manager_client) { if (manager_res) {
destroy_manager_client(manager_client); destroy_manager_resource(manager_res);
} }
} }
static void static void
group_send_details(struct wlr_ext_workspace_group_client_v1 *group_client) { group_send_details(struct wlr_ext_workspace_group_v1_resource *group_res) {
struct wlr_ext_workspace_group_handle_v1 *group = group_client->group; struct wlr_ext_workspace_group_handle_v1 *group = group_res->group;
struct wl_resource *resource = group_client->resource; struct wl_resource *resource = group_res->resource;
struct wl_client *client = wl_resource_get_client(resource); struct wl_client *client = wl_resource_get_client(resource);
ext_workspace_group_handle_v1_send_capabilities(resource, group->caps); ext_workspace_group_handle_v1_send_capabilities(resource, group->caps);
@@ -430,65 +462,67 @@ static void manager_bind(struct wl_client *client, void *data, uint32_t version,
uint32_t id) { uint32_t id) {
struct wlr_ext_workspace_manager_v1 *manager = data; struct wlr_ext_workspace_manager_v1 *manager = data;
struct wlr_ext_workspace_manager_client_v1 *manager_client = struct wlr_ext_workspace_manager_v1_resource *manager_res =
calloc(1, sizeof(*manager_client)); calloc(1, sizeof(*manager_res));
if (!manager_client) { if (!manager_res) {
wl_client_post_no_memory(client); wl_client_post_no_memory(client);
return; return;
} }
manager_client->manager = manager; manager_res->manager = manager;
wl_list_init(&manager_client->requests); wl_list_init(&manager_res->requests);
wl_list_insert(&manager->clients, &manager_client->link); wl_list_init(&manager_res->workspace_resources);
wl_list_init(&manager_res->group_resources);
manager_client->resource = wl_resource_create( manager_res->resource = wl_resource_create(
client, &ext_workspace_manager_v1_interface, version, id); client, &ext_workspace_manager_v1_interface, version, id);
if (!manager_client->resource) { if (!manager_res->resource) {
free(manager_client); free(manager_res);
wl_client_post_no_memory(client); wl_client_post_no_memory(client);
return; return;
} }
wl_resource_set_implementation(manager_client->resource, &manager_impl, wl_resource_set_implementation(manager_res->resource, &manager_impl,
manager_client, manager_resource_destroy); manager_res, manager_resource_destroy);
wl_list_insert(&manager->resources, &manager_res->link);
struct wlr_ext_workspace_group_handle_v1 *group; struct wlr_ext_workspace_group_handle_v1 *group;
wl_list_for_each(group, &manager->groups, link) { wl_list_for_each(group, &manager->groups, link) {
struct wlr_ext_workspace_group_client_v1 *group_client = struct wlr_ext_workspace_group_v1_resource *group_res =
create_group_client(group, manager_client); create_group_resource(group, manager_res);
if (!group_client) { if (!group_res) {
wl_resource_post_no_memory(manager_client->resource); wl_resource_post_no_memory(manager_res->resource);
continue; continue;
} }
ext_workspace_manager_v1_send_workspace_group(manager_client->resource, ext_workspace_manager_v1_send_workspace_group(manager_res->resource,
group_client->resource); group_res->resource);
group_send_details(group_client); group_send_details(group_res);
} }
struct wlr_ext_workspace_handle_v1 *workspace; struct wlr_ext_workspace_handle_v1 *workspace;
wl_list_for_each(workspace, &manager->workspaces, link) { wl_list_for_each(workspace, &manager->workspaces, link) {
struct wlr_ext_workspace_client_v1 *workspace_client = struct wlr_ext_workspace_v1_resource *workspace_res =
create_workspace_client(workspace, manager_client); create_workspace_resource(workspace, manager_res);
if (!workspace) { if (!workspace_res) {
wl_client_post_no_memory(client); wl_resource_post_no_memory(manager_res->resource);
continue; continue;
} }
ext_workspace_manager_v1_send_workspace(manager_client->resource, ext_workspace_manager_v1_send_workspace(manager_res->resource,
workspace_client->resource); workspace_res->resource);
workspace_send_details(workspace_client); workspace_send_details(workspace_res);
if (!workspace->group) { if (!workspace->group) {
continue; continue;
} }
struct wlr_ext_workspace_group_client_v1 *group_client; struct wlr_ext_workspace_group_v1_resource *group_res;
wl_list_for_each(group_client, &workspace->group->clients, link) { wl_list_for_each(group_res, &workspace->group->resources, link) {
if (group_client->manager == manager_client) { if (group_res->manager == manager_res) {
ext_workspace_group_handle_v1_send_workspace_enter( ext_workspace_group_handle_v1_send_workspace_enter(
group_client->resource, workspace_client->resource); group_res->resource, workspace_res->resource);
} }
} }
} }
manager_schedule_done(manager); ext_workspace_manager_v1_send_done(manager_res->resource);
} }
static void manager_handle_display_destroy(struct wl_listener *listener, static void manager_handle_display_destroy(struct wl_listener *listener,
@@ -509,9 +543,9 @@ static void manager_handle_display_destroy(struct wl_listener *listener,
wlr_ext_workspace_handle_v1_destroy(workspace); wlr_ext_workspace_handle_v1_destroy(workspace);
} }
struct wlr_ext_workspace_manager_client_v1 *manager_client, *tmp3; struct wlr_ext_workspace_manager_v1_resource *manager_res, *tmp3;
wl_list_for_each_safe(manager_client, tmp3, &manager->clients, link) { wl_list_for_each_safe(manager_res, tmp3, &manager->resources, link) {
destroy_manager_client(manager_client); destroy_manager_resource(manager_res);
} }
if (manager->idle_source) { if (manager->idle_source) {
@@ -548,7 +582,7 @@ wlr_ext_workspace_manager_v1_create(struct wl_display *display,
wl_list_init(&manager->groups); wl_list_init(&manager->groups);
wl_list_init(&manager->workspaces); wl_list_init(&manager->workspaces);
wl_list_init(&manager->clients); wl_list_init(&manager->resources);
wl_signal_init(&manager->events.destroy); wl_signal_init(&manager->events.destroy);
return manager; return manager;
@@ -566,22 +600,22 @@ wlr_ext_workspace_group_handle_v1_create(
group->caps = caps; group->caps = caps;
wl_list_init(&group->outputs); wl_list_init(&group->outputs);
wl_list_init(&group->clients); wl_list_init(&group->resources);
wl_signal_init(&group->events.create_workspace); wl_signal_init(&group->events.create_workspace);
wl_signal_init(&group->events.destroy); wl_signal_init(&group->events.destroy);
wl_list_insert(manager->groups.prev, &group->link); wl_list_insert(manager->groups.prev, &group->link);
struct wlr_ext_workspace_manager_client_v1 *manager_client; struct wlr_ext_workspace_manager_v1_resource *manager_res;
wl_list_for_each(manager_client, &manager->clients, link) { wl_list_for_each(manager_res, &manager->resources, link) {
struct wlr_ext_workspace_group_client_v1 *group_client = struct wlr_ext_workspace_group_v1_resource *group_res =
create_group_client(group, manager_client); create_group_resource(group, manager_res);
if (!group_client) { if (!group_res) {
continue; continue;
} }
ext_workspace_manager_v1_send_workspace_group(manager_client->resource, ext_workspace_manager_v1_send_workspace_group(manager_res->resource,
group_client->resource); group_res->resource);
group_send_details(group_client); group_send_details(group_res);
} }
manager_schedule_done(manager); manager_schedule_done(manager);
@@ -594,19 +628,19 @@ workspace_send_group(struct wlr_ext_workspace_handle_v1 *workspace,
struct wlr_ext_workspace_group_handle_v1 *group, struct wlr_ext_workspace_group_handle_v1 *group,
bool enter) { bool enter) {
struct wlr_ext_workspace_client_v1 *workspace_client; struct wlr_ext_workspace_v1_resource *workspace_res;
wl_list_for_each(workspace_client, &workspace->clients, link) { wl_list_for_each(workspace_res, &workspace->resources, link) {
struct wlr_ext_workspace_group_client_v1 *group_client; struct wlr_ext_workspace_group_v1_resource *group_res;
wl_list_for_each(group_client, &group->clients, link) { wl_list_for_each(group_res, &group->resources, link) {
if (group_client->manager != workspace_client->manager) { if (group_res->manager != workspace_res->manager) {
continue; continue;
} }
if (enter) { if (enter) {
ext_workspace_group_handle_v1_send_workspace_enter( ext_workspace_group_handle_v1_send_workspace_enter(
group_client->resource, workspace_client->resource); group_res->resource, workspace_res->resource);
} else { } else {
ext_workspace_group_handle_v1_send_workspace_leave( ext_workspace_group_handle_v1_send_workspace_leave(
group_client->resource, workspace_client->resource); group_res->resource, workspace_res->resource);
} }
} }
} }
@@ -625,10 +659,9 @@ destroy_group_output(struct wlr_ext_workspace_v1_group_output *group_output) {
static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group, static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group,
struct wlr_output *output, bool enter) { struct wlr_output *output, bool enter) {
struct wlr_ext_workspace_group_client_v1 *group_client; struct wlr_ext_workspace_group_v1_resource *group_res;
wl_list_for_each(group_client, &group->clients, link) { wl_list_for_each(group_res, &group->resources, link) {
struct wl_client *client = struct wl_client *client = wl_resource_get_client(group_res->resource);
wl_resource_get_client(group_client->resource);
struct wl_resource *output_resource; struct wl_resource *output_resource;
wl_resource_for_each(output_resource, &output->resources) { wl_resource_for_each(output_resource, &output->resources) {
@@ -637,10 +670,10 @@ static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group,
} }
if (enter) { if (enter) {
ext_workspace_group_handle_v1_send_output_enter( ext_workspace_group_handle_v1_send_output_enter(
group_client->resource, output_resource); group_res->resource, output_resource);
} else { } else {
ext_workspace_group_handle_v1_send_output_leave( ext_workspace_group_handle_v1_send_output_leave(
group_client->resource, output_resource); group_res->resource, output_resource);
} }
} }
} }
@@ -650,6 +683,10 @@ static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group,
void wlr_ext_workspace_group_handle_v1_destroy( void wlr_ext_workspace_group_handle_v1_destroy(
struct wlr_ext_workspace_group_handle_v1 *group) { struct wlr_ext_workspace_group_handle_v1 *group) {
if (!group) {
return;
}
wl_signal_emit_mutable(&group->events.destroy, NULL); wl_signal_emit_mutable(&group->events.destroy, NULL);
assert(wl_list_empty(&group->events.create_workspace.listener_list)); assert(wl_list_empty(&group->events.create_workspace.listener_list));
@@ -663,16 +700,16 @@ void wlr_ext_workspace_group_handle_v1_destroy(
} }
} }
struct wlr_ext_workspace_group_client_v1 *group_client, *tmp; struct wlr_ext_workspace_group_v1_resource *group_res, *tmp;
wl_list_for_each_safe(group_client, tmp, &group->clients, link) { wl_list_for_each_safe(group_res, tmp, &group->resources, link) {
ext_workspace_group_handle_v1_send_removed(group_client->resource); ext_workspace_group_handle_v1_send_removed(group_res->resource);
destroy_group_client(group_client); destroy_group_resource(group_res);
} }
struct wlr_ext_workspace_manager_client_v1 *manager_client; struct wlr_ext_workspace_manager_v1_resource *manager_res;
wl_list_for_each(manager_client, &group->manager->clients, link) { wl_list_for_each(manager_res, &group->manager->resources, link) {
struct wlr_ext_workspace_v1_request *req, *tmp2; struct wlr_ext_workspace_v1_request *req, *tmp2;
wl_list_for_each_safe(req, tmp2, &manager_client->requests, link) { wl_list_for_each_safe(req, tmp2, &manager_res->requests, link) {
if (req->group == group) { if (req->group == group) {
destroy_request(req); destroy_request(req);
} }
@@ -697,11 +734,11 @@ static void handle_output_bind(struct wl_listener *listener, void *data) {
struct wlr_output_event_bind *event = data; struct wlr_output_event_bind *event = data;
struct wl_client *client = wl_resource_get_client(event->resource); struct wl_client *client = wl_resource_get_client(event->resource);
struct wlr_ext_workspace_group_client_v1 *group_client; struct wlr_ext_workspace_group_v1_resource *group_res;
wl_list_for_each(group_client, &group_output->group->clients, link) { wl_list_for_each(group_res, &group_output->group->resources, link) {
if (wl_resource_get_client(group_client->resource) == client) { if (wl_resource_get_client(group_res->resource) == client) {
ext_workspace_group_handle_v1_send_output_enter( ext_workspace_group_handle_v1_send_output_enter(group_res->resource,
group_client->resource, event->resource); event->resource);
} }
} }
@@ -778,11 +815,12 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager,
if (id) { if (id) {
workspace->id = strdup(id); workspace->id = strdup(id);
if (!workspace->id) { if (!workspace->id) {
free(workspace);
return NULL; return NULL;
} }
} }
wl_list_init(&workspace->clients); wl_list_init(&workspace->resources);
wl_array_init(&workspace->coordinates); wl_array_init(&workspace->coordinates);
wl_signal_init(&workspace->events.activate); wl_signal_init(&workspace->events.activate);
wl_signal_init(&workspace->events.deactivate); wl_signal_init(&workspace->events.deactivate);
@@ -792,16 +830,16 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager,
wl_list_insert(&manager->workspaces, &workspace->link); wl_list_insert(&manager->workspaces, &workspace->link);
struct wlr_ext_workspace_manager_client_v1 *manager_client; struct wlr_ext_workspace_manager_v1_resource *manager_res;
wl_list_for_each(manager_client, &manager->clients, link) { wl_list_for_each(manager_res, &manager->resources, link) {
struct wlr_ext_workspace_client_v1 *workspace_client = struct wlr_ext_workspace_v1_resource *workspace_res =
create_workspace_client(workspace, manager_client); create_workspace_resource(workspace, manager_res);
if (!workspace_client) { if (!workspace_res) {
continue; continue;
} }
ext_workspace_manager_v1_send_workspace(manager_client->resource, ext_workspace_manager_v1_send_workspace(manager_res->resource,
workspace_client->resource); workspace_res->resource);
workspace_send_details(workspace_client); workspace_send_details(workspace_res);
} }
manager_schedule_done(manager); manager_schedule_done(manager);
@@ -811,6 +849,10 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager,
void wlr_ext_workspace_handle_v1_destroy( void wlr_ext_workspace_handle_v1_destroy(
struct wlr_ext_workspace_handle_v1 *workspace) { struct wlr_ext_workspace_handle_v1 *workspace) {
if (!workspace) {
return;
}
wl_signal_emit_mutable(&workspace->events.destroy, NULL); wl_signal_emit_mutable(&workspace->events.destroy, NULL);
assert(wl_list_empty(&workspace->events.activate.listener_list)); assert(wl_list_empty(&workspace->events.activate.listener_list));
@@ -823,16 +865,16 @@ void wlr_ext_workspace_handle_v1_destroy(
workspace_send_group(workspace, workspace->group, false); workspace_send_group(workspace, workspace->group, false);
} }
struct wlr_ext_workspace_client_v1 *workspace_client, *tmp; struct wlr_ext_workspace_v1_resource *workspace_res, *tmp;
wl_list_for_each_safe(workspace_client, tmp, &workspace->clients, link) { wl_list_for_each_safe(workspace_res, tmp, &workspace->resources, link) {
ext_workspace_handle_v1_send_removed(workspace_client->resource); ext_workspace_handle_v1_send_removed(workspace_res->resource);
destroy_workspace_client(workspace_client); destroy_workspace_resource(workspace_res);
} }
struct wlr_ext_workspace_manager_client_v1 *manager_client; struct wlr_ext_workspace_manager_v1_resource *manager_res;
wl_list_for_each(manager_client, &workspace->manager->clients, link) { wl_list_for_each(manager_res, &workspace->manager->resources, link) {
struct wlr_ext_workspace_v1_request *req, *tmp2; struct wlr_ext_workspace_v1_request *req, *tmp2;
wl_list_for_each_safe(req, tmp2, &manager_client->requests, link) { wl_list_for_each_safe(req, tmp2, &manager_res->requests, link) {
if (req->workspace == workspace) { if (req->workspace == workspace) {
destroy_request(req); destroy_request(req);
} }
@@ -856,7 +898,7 @@ void wlr_ext_workspace_handle_v1_set_group(
} }
if (workspace->group) { if (workspace->group) {
workspace_send_group(workspace, group, false); workspace_send_group(workspace, workspace->group, false);
} }
workspace->group = group; workspace->group = group;
if (group) { if (group) {
@@ -878,9 +920,9 @@ void wlr_ext_workspace_handle_v1_set_name(
return; return;
} }
struct wlr_ext_workspace_client_v1 *workspace_client; struct wlr_ext_workspace_v1_resource *workspace_res;
wl_list_for_each(workspace_client, &workspace->clients, link) { wl_list_for_each(workspace_res, &workspace->resources, link) {
ext_workspace_handle_v1_send_name(workspace_client->resource, ext_workspace_handle_v1_send_name(workspace_res->resource,
workspace->name); workspace->name);
} }
@@ -905,9 +947,9 @@ void wlr_ext_workspace_handle_v1_set_coordinates(
wl_array_init(&workspace->coordinates); wl_array_init(&workspace->coordinates);
wl_array_copy(&workspace->coordinates, coordinates); wl_array_copy(&workspace->coordinates, coordinates);
struct wlr_ext_workspace_client_v1 *workspace_client; struct wlr_ext_workspace_v1_resource *workspace_res;
wl_list_for_each(workspace_client, &workspace->clients, link) { wl_list_for_each(workspace_res, &workspace->resources, link) {
ext_workspace_handle_v1_send_coordinates(workspace_client->resource, ext_workspace_handle_v1_send_coordinates(workspace_res->resource,
&workspace->coordinates); &workspace->coordinates);
} }
@@ -927,9 +969,9 @@ static void workspace_set_state(struct wlr_ext_workspace_handle_v1 *workspace,
return; return;
} }
struct wlr_ext_workspace_client_v1 *workspace_client; struct wlr_ext_workspace_v1_resource *workspace_res;
wl_list_for_each(workspace_client, &workspace->clients, link) { wl_list_for_each(workspace_res, &workspace->resources, link) {
ext_workspace_handle_v1_send_state(workspace_client->resource, ext_workspace_handle_v1_send_state(workspace_res->resource,
workspace->state); workspace->state);
} }

View File

@@ -2,32 +2,11 @@
// TODO: remove this file // TODO: remove this file
// refer: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5115 // refer: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5115
/* #include <wayland-protocols/ext-workspace-v1-enum.h>
* This an unstable interface of wlroots. No guarantees are made regarding the
* future consistency of this API.
*/
#ifndef WLR_USE_UNSTABLE
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
#endif
#ifndef WLR_TYPES_WLR_EXT_WORKSPACE_V1_H
#define WLR_TYPES_WLR_EXT_WORKSPACE_V1_H
#include <wayland-server-core.h> #include <wayland-server-core.h>
struct wlr_output; struct wlr_output;
enum wlr_ext_workspace_group_handle_v1_cap {
WLR_EXT_WORKSPACE_GROUP_HANDLE_V1_CAP_CREATE_WORKSPACE = 1 << 0,
};
enum wlr_ext_workspace_handle_v1_cap {
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ACTIVATE = 1 << 0,
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_DEACTIVATE = 1 << 1,
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_REMOVE = 1 << 2,
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ASSIGN = 1 << 3,
};
struct wlr_ext_workspace_manager_v1 { struct wlr_ext_workspace_manager_v1 {
struct wl_global *global; struct wl_global *global;
struct wl_list groups; // wlr_ext_workspace_group_handle_v1.link struct wl_list groups; // wlr_ext_workspace_group_handle_v1.link
@@ -37,24 +16,33 @@ struct wlr_ext_workspace_manager_v1 {
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;
struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link struct {
struct wl_event_source *idle_source; struct wl_list resources; // wlr_ext_workspace_manager_v1_resource.link
struct wl_event_loop *event_loop; struct wl_event_source *idle_source;
struct wl_listener display_destroy; struct wl_event_loop *event_loop;
struct wl_listener display_destroy;
};
};
struct wlr_ext_workspace_group_handle_v1_create_workspace_event {
const char *name;
}; };
struct wlr_ext_workspace_group_handle_v1 { struct wlr_ext_workspace_group_handle_v1 {
struct wlr_ext_workspace_manager_v1 *manager; struct wlr_ext_workspace_manager_v1 *manager;
uint32_t caps; // wlr_ext_workspace_group_handle_v1_cap uint32_t caps; // ext_workspace_group_handle_v1_group_capabilities
struct { struct {
struct wl_signal create_workspace; // const char * struct wl_signal
create_workspace; // wlr_ext_workspace_group_handle_v1_create_workspace_event
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;
struct wl_list link; // wlr_ext_workspace_manager_v1.groups struct wl_list link; // wlr_ext_workspace_manager_v1.groups
struct wl_list outputs; // wlr_ext_workspace_v1_group_output.link struct {
struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link struct wl_list outputs; // wlr_ext_workspace_v1_group_output.link
struct wl_list resources; // wlr_ext_workspace_manager_v1_resource.link
};
}; };
struct wlr_ext_workspace_handle_v1 { struct wlr_ext_workspace_handle_v1 {
@@ -63,7 +51,7 @@ struct wlr_ext_workspace_handle_v1 {
char *id; char *id;
char *name; char *name;
struct wl_array coordinates; struct wl_array coordinates;
uint32_t caps; // wlr_ext_workspace_handle_v1_cap uint32_t caps; // ext_workspace_handle_v1_workspace_capabilities
uint32_t state; // ext_workspace_handle_v1_state uint32_t state; // ext_workspace_handle_v1_state
struct { struct {
@@ -74,9 +62,11 @@ struct wlr_ext_workspace_handle_v1 {
struct wl_signal destroy; struct wl_signal destroy;
} events; } events;
struct wl_list link; // wlr_ext_workspace_manager_v1.workspaces; struct wl_list link; // wlr_ext_workspace_manager_v1.workspaces
struct wl_list clients; struct {
struct wl_list resources; // wlr_ext_workspace_v1_resource.link
};
}; };
struct wlr_ext_workspace_manager_v1 * struct wlr_ext_workspace_manager_v1 *
@@ -114,5 +104,3 @@ void wlr_ext_workspace_handle_v1_set_urgent(
struct wlr_ext_workspace_handle_v1 *workspace, bool enabled); struct wlr_ext_workspace_handle_v1 *workspace, bool enabled);
void wlr_ext_workspace_handle_v1_set_hidden( void wlr_ext_workspace_handle_v1_set_hidden(
struct wlr_ext_workspace_handle_v1 *workspace, bool enabled); struct wlr_ext_workspace_handle_v1 *workspace, bool enabled);
#endif

View File

@@ -389,30 +389,21 @@ Client *focustop(Monitor *m) {
Client *get_next_stack_client(Client *c, bool reverse) { Client *get_next_stack_client(Client *c, bool reverse) {
if (!c || !c->mon) if (!c || !c->mon)
return NULL; // 添加输入检查 return NULL;
Client *next = NULL; Client *next = NULL;
if (reverse) { if (reverse) {
wl_list_for_each_reverse(next, &c->link, link) { wl_list_for_each_reverse(next, &c->link, link) {
if (!next) if (&next->link == &clients)
continue; // 安全检查 continue; /* wrap past the sentinel node */
if (c->mon->has_visible_fullscreen_client && !next->isfloating &&
!next->isfullscreen)
continue;
// 添加更安全的 VISIBLEON 检查
if (next != c && next->mon && VISIBLEON(next, c->mon)) if (next != c && next->mon && VISIBLEON(next, c->mon))
return next; return next;
} }
} else { } else {
wl_list_for_each(next, &c->link, link) { wl_list_for_each(next, &c->link, link) {
if (!next) if (&next->link == &clients)
continue; // 安全检查 continue; /* wrap past the sentinel node */
if (c->mon->has_visible_fullscreen_client && !next->isfloating &&
!next->isfullscreen)
continue;
if (next != c && next->mon && VISIBLEON(next, c->mon)) if (next != c && next->mon && VISIBLEON(next, c->mon))
return next; return next;

View File

@@ -5,7 +5,7 @@ void set_size_per(Monitor *m, Client *c) {
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) { if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
c->master_mfact_per = fc->master_mfact_per; c->master_mfact_per = fc->master_mfact_per;
c->master_inner_per = fc->master_inner_per; c->master_inner_per = fc->master_inner_per;
c->stack_innder_per = fc->stack_innder_per; c->stack_inner_per = fc->stack_inner_per;
found = true; found = true;
break; break;
} }
@@ -14,7 +14,7 @@ void set_size_per(Monitor *m, Client *c) {
if (!found) { if (!found) {
c->master_mfact_per = m->pertag->mfacts[m->pertag->curtag]; c->master_mfact_per = m->pertag->mfacts[m->pertag->curtag];
c->master_inner_per = 1.0f; c->master_inner_per = 1.0f;
c->stack_innder_per = 1.0f; c->stack_inner_per = 1.0f;
} }
} }
@@ -70,7 +70,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
// 记录初始状态 // 记录初始状态
grabc->old_master_mfact_per = grabc->master_mfact_per; grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per; grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per; grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->cursor_in_upper_half = grabc->cursor_in_upper_half =
cursor->y < grabc->geom.y + grabc->geom.height / 2; cursor->y < grabc->geom.y + grabc->geom.height / 2;
grabc->cursor_in_left_half = grabc->cursor_in_left_half =
@@ -86,7 +86,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
} else { } else {
grabc->old_master_mfact_per = grabc->master_mfact_per; grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per; grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per; grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom; grabc->drag_begin_geom = grabc->geom;
grabc->cursor_in_upper_half = true; grabc->cursor_in_upper_half = true;
grabc->cursor_in_left_half = false; grabc->cursor_in_left_half = false;
@@ -100,7 +100,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
} else { } else {
delta_x = (float)(offsetx) * (1 - grabc->old_master_mfact_per) / delta_x = (float)(offsetx) * (1 - grabc->old_master_mfact_per) /
grabc->drag_begin_geom.width; grabc->drag_begin_geom.width;
delta_y = (float)(offsety) * (grabc->old_stack_innder_per) / delta_y = (float)(offsety) * (grabc->old_stack_inner_per) /
grabc->drag_begin_geom.height; grabc->drag_begin_geom.height;
} }
bool moving_up; bool moving_up;
@@ -182,12 +182,12 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
// 直接设置新的比例,基于初始值 + 变化量 // 直接设置新的比例,基于初始值 + 变化量
float new_master_mfact_per = grabc->old_master_mfact_per + delta_x; float new_master_mfact_per = grabc->old_master_mfact_per + delta_x;
float new_master_inner_per = grabc->old_master_inner_per + delta_y; float new_master_inner_per = grabc->old_master_inner_per + delta_y;
float new_stack_innder_per = grabc->old_stack_innder_per + delta_y; float new_stack_inner_per = grabc->old_stack_inner_per + delta_y;
// 应用限制,确保比例在合理范围内 // 应用限制,确保比例在合理范围内
new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per)); new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per));
new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per)); new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per));
new_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per)); new_stack_inner_per = fmaxf(0.1f, fminf(0.9f, new_stack_inner_per));
// 应用到所有平铺窗口 // 应用到所有平铺窗口
wl_list_for_each(tc, &clients, link) { wl_list_for_each(tc, &clients, link) {
@@ -197,7 +197,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
} }
grabc->master_inner_per = new_master_inner_per; grabc->master_inner_per = new_master_inner_per;
grabc->stack_innder_per = new_stack_innder_per; grabc->stack_inner_per = new_stack_inner_per;
if (!isdrag) { if (!isdrag) {
arrange(grabc->mon, false); arrange(grabc->mon, false);
@@ -250,7 +250,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
// 记录初始状态 // 记录初始状态
grabc->old_master_mfact_per = grabc->master_mfact_per; grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per; grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per; grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->cursor_in_upper_half = grabc->cursor_in_upper_half =
cursor->y < grabc->geom.y + grabc->geom.height / 2; cursor->y < grabc->geom.y + grabc->geom.height / 2;
grabc->cursor_in_left_half = grabc->cursor_in_left_half =
@@ -267,7 +267,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
} else { } else {
grabc->old_master_mfact_per = grabc->master_mfact_per; grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per; grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per; grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom; grabc->drag_begin_geom = grabc->geom;
grabc->cursor_in_upper_half = true; grabc->cursor_in_upper_half = true;
grabc->cursor_in_left_half = false; grabc->cursor_in_left_half = false;
@@ -280,7 +280,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
delta_y = (float)(offsety) * (grabc->old_master_mfact_per) / delta_y = (float)(offsety) * (grabc->old_master_mfact_per) /
grabc->drag_begin_geom.height; grabc->drag_begin_geom.height;
} else { } else {
delta_x = (float)(offsetx) * (grabc->old_stack_innder_per) / delta_x = (float)(offsetx) * (grabc->old_stack_inner_per) /
grabc->drag_begin_geom.width; grabc->drag_begin_geom.width;
delta_y = (float)(offsety) * (1 - grabc->old_master_mfact_per) / delta_y = (float)(offsety) * (1 - grabc->old_master_mfact_per) /
grabc->drag_begin_geom.height; grabc->drag_begin_geom.height;
@@ -338,13 +338,13 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
delta_y; // 垂直delta_y调整主区域高度 delta_y; // 垂直delta_y调整主区域高度
float new_master_inner_per = grabc->old_master_inner_per + float new_master_inner_per = grabc->old_master_inner_per +
delta_x; // 垂直delta_x调整主区域内部宽度 delta_x; // 垂直delta_x调整主区域内部宽度
float new_stack_innder_per = grabc->old_stack_innder_per + float new_stack_inner_per = grabc->old_stack_inner_per +
delta_x; // 垂直delta_x调整栈区域内部宽度 delta_x; // 垂直delta_x调整栈区域内部宽度
// 应用限制,确保比例在合理范围内 // 应用限制,确保比例在合理范围内
new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per)); new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per));
new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per)); new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per));
new_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per)); new_stack_inner_per = fmaxf(0.1f, fminf(0.9f, new_stack_inner_per));
// 应用到所有平铺窗口 // 应用到所有平铺窗口
wl_list_for_each(tc, &clients, link) { wl_list_for_each(tc, &clients, link) {
@@ -354,7 +354,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
} }
grabc->master_inner_per = new_master_inner_per; grabc->master_inner_per = new_master_inner_per;
grabc->stack_innder_per = new_stack_innder_per; grabc->stack_inner_per = new_stack_inner_per;
if (!isdrag) { if (!isdrag) {
arrange(grabc->mon, false); arrange(grabc->mon, false);
@@ -402,7 +402,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety,
} else { } else {
grabc->old_master_mfact_per = grabc->master_mfact_per; grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per; grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per; grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom; grabc->drag_begin_geom = grabc->geom;
grabc->old_scroller_pproportion = grabc->scroller_proportion; grabc->old_scroller_pproportion = grabc->scroller_proportion;
grabc->cursor_in_upper_half = false; grabc->cursor_in_upper_half = false;
@@ -485,7 +485,8 @@ void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety,
const Layout *current_layout = const Layout *current_layout =
grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag]; grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag];
if (current_layout->id == TILE || current_layout->id == DECK || if (current_layout->id == TILE || current_layout->id == DECK ||
current_layout->id == CENTER_TILE || current_layout->id == RIGHT_TILE current_layout->id == CENTER_TILE || current_layout->id == RIGHT_TILE ||
(current_layout->id == TGMIX && grabc->mon->visible_tiling_clients <= 3)
) { ) {
resize_tile_master_horizontal(grabc, isdrag, offsetx, offsety, time, resize_tile_master_horizontal(grabc, isdrag, offsetx, offsety, time,
@@ -520,16 +521,16 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
if (VISIBLEON(c, m) && ISTILED(c)) { if (VISIBLEON(c, m) && ISTILED(c)) {
if (total_master_inner_percent > 0.0 && i < nmasters) { if (total_master_inner_percent > 0.0 && i < nmasters) {
c->ismaster = true; c->ismaster = true;
c->stack_innder_per = stack_num ? 1.0f / stack_num : 1.0f; c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
c->master_inner_per = c->master_inner_per =
c->master_inner_per / total_master_inner_percent; c->master_inner_per / total_master_inner_percent;
} else { } else {
c->ismaster = false; c->ismaster = false;
c->master_inner_per = c->master_inner_per =
master_num > 0 ? 1.0f / master_num : 1.0f; master_num > 0 ? 1.0f / master_num : 1.0f;
c->stack_innder_per = c->stack_inner_per =
total_stack_hight_percent total_stack_hight_percent
? c->stack_innder_per / total_stack_hight_percent ? c->stack_inner_per / total_stack_hight_percent
: 1.0f; : 1.0f;
} }
i++; i++;
@@ -541,11 +542,11 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
if (total_master_inner_percent > 0.0 && i < nmasters) { if (total_master_inner_percent > 0.0 && i < nmasters) {
c->ismaster = true; c->ismaster = true;
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) { if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
c->stack_innder_per = c->stack_inner_per =
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f; stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f;
} else { } else {
c->stack_innder_per = c->stack_inner_per =
stack_num > 1 ? 2.0f / stack_num : 1.0f; stack_num > 1 ? 2.0f / stack_num : 1.0f;
} }
@@ -558,15 +559,15 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
c->master_inner_per = c->master_inner_per =
master_num > 0 ? 1.0f / master_num : 1.0f; master_num > 0 ? 1.0f / master_num : 1.0f;
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) { if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
c->stack_innder_per = c->stack_inner_per =
total_right_stack_hight_percent total_right_stack_hight_percent
? c->stack_innder_per / ? c->stack_inner_per /
total_right_stack_hight_percent total_right_stack_hight_percent
: 1.0f; : 1.0f;
} else { } else {
c->stack_innder_per = c->stack_inner_per =
total_left_stack_hight_percent total_left_stack_hight_percent
? c->stack_innder_per / ? c->stack_inner_per /
total_left_stack_hight_percent total_left_stack_hight_percent
: 1.0f; : 1.0f;
} }
@@ -580,7 +581,7 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
void // 17 void // 17
arrange(Monitor *m, bool want_animation) { arrange(Monitor *m, bool want_animation) {
Client *c = NULL; Client *c = NULL;
double total_stack_innder_percent = 0; double total_stack_inner_percent = 0;
double total_master_inner_percent = 0; double total_master_inner_percent = 0;
double total_right_stack_hight_percent = 0; double total_right_stack_hight_percent = 0;
double total_left_stack_hight_percent = 0; double total_left_stack_hight_percent = 0;
@@ -598,7 +599,6 @@ arrange(Monitor *m, bool want_animation) {
m->visible_clients = 0; m->visible_clients = 0;
m->visible_tiling_clients = 0; m->visible_tiling_clients = 0;
m->visible_scroll_tiling_clients = 0; m->visible_scroll_tiling_clients = 0;
m->has_visible_fullscreen_client = false;
wl_list_for_each(c, &clients, link) { wl_list_for_each(c, &clients, link) {
@@ -612,9 +612,6 @@ arrange(Monitor *m, bool want_animation) {
if (!c->isunglobal) if (!c->isunglobal)
m->visible_clients++; m->visible_clients++;
if (c->isfullscreen)
m->has_visible_fullscreen_client = true;
if (ISTILED(c)) { if (ISTILED(c)) {
m->visible_tiling_clients++; m->visible_tiling_clients++;
} }
@@ -640,17 +637,17 @@ arrange(Monitor *m, bool want_animation) {
total_master_inner_percent += c->master_inner_per; total_master_inner_percent += c->master_inner_per;
} else { } else {
stack_num++; stack_num++;
total_stack_innder_percent += c->stack_innder_per; total_stack_inner_percent += c->stack_inner_per;
stack_index = i - nmasters; stack_index = i - nmasters;
if ((stack_index % 2) ^ if ((stack_index % 2) ^
(m->visible_tiling_clients % 2 == 0)) { (m->visible_tiling_clients % 2 == 0)) {
c->isleftstack = false; c->isleftstack = false;
total_right_stack_hight_percent += total_right_stack_hight_percent +=
c->stack_innder_per; c->stack_inner_per;
} else { } else {
c->isleftstack = true; c->isleftstack = true;
total_left_stack_hight_percent += total_left_stack_hight_percent +=
c->stack_innder_per; c->stack_inner_per;
} }
} }
@@ -671,7 +668,7 @@ arrange(Monitor *m, bool want_animation) {
reset_size_per_mon( reset_size_per_mon(
m, m->visible_tiling_clients, total_left_stack_hight_percent, m, m->visible_tiling_clients, total_left_stack_hight_percent,
total_right_stack_hight_percent, total_stack_innder_percent, total_right_stack_hight_percent, total_stack_inner_percent,
total_master_inner_percent, master_num, stack_num); total_master_inner_percent, master_num, stack_num);
if (m->isoverview) { if (m->isoverview) {

View File

@@ -705,17 +705,17 @@ void center_tile(Monitor *m) {
if (n - nmasters == 1) { if (n - nmasters == 1) {
// 单个堆叠窗口 // 单个堆叠窗口
r = n - i; r = n - i;
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
h = (m->w.height - 2 * cur_gappov - h = (m->w.height - 2 * cur_gappov -
cur_gappiv * ie * (stack_num - 1)) * cur_gappiv * ie * (stack_num - 1)) *
c->stack_innder_per; c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
h = (m->w.height - ety - cur_gappov - h = (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)) / cur_gappiv * ie * (r - 1)) /
r; r;
c->stack_innder_per = h / (m->w.height - ety - cur_gappov - c->stack_inner_per = h / (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)); cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} }
@@ -741,19 +741,19 @@ void center_tile(Monitor *m) {
if ((stack_index % 2) ^ (n % 2 == 0)) { if ((stack_index % 2) ^ (n % 2 == 0)) {
// 右侧堆叠窗口 // 右侧堆叠窗口
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
h = slave_right_surplus_height * c->stack_innder_per / h = slave_right_surplus_height * c->stack_inner_per /
slave_right_surplus_ratio; slave_right_surplus_ratio;
slave_right_surplus_height = slave_right_surplus_height =
slave_right_surplus_height - h; slave_right_surplus_height - h;
slave_right_surplus_ratio = slave_right_surplus_ratio =
slave_right_surplus_ratio - c->stack_innder_per; slave_right_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
h = (m->w.height - ety - cur_gappov - h = (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)) / cur_gappiv * ie * (r - 1)) /
r; r;
c->stack_innder_per = c->stack_inner_per =
h / (m->w.height - ety - cur_gappov - h / (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)); cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
@@ -770,19 +770,19 @@ void center_tile(Monitor *m) {
ety += c->geom.height + cur_gappiv * ie; ety += c->geom.height + cur_gappiv * ie;
} else { } else {
// 左侧堆叠窗口 // 左侧堆叠窗口
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
h = slave_left_surplus_height * c->stack_innder_per / h = slave_left_surplus_height * c->stack_inner_per /
slave_left_surplus_ratio; slave_left_surplus_ratio;
slave_left_surplus_height = slave_left_surplus_height =
slave_left_surplus_height - h; slave_left_surplus_height - h;
slave_left_surplus_ratio = slave_left_surplus_ratio =
slave_left_surplus_ratio - c->stack_innder_per; slave_left_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
h = (m->w.height - oty - cur_gappov - h = (m->w.height - oty - cur_gappov -
cur_gappiv * ie * (r - 1)) / cur_gappiv * ie * (r - 1)) /
r; r;
c->stack_innder_per = c->stack_inner_per =
h / (m->w.height - oty - cur_gappov - h / (m->w.height - oty - cur_gappov -
cur_gappiv * ie * (r - 1)); cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
@@ -884,22 +884,22 @@ void tile(Monitor *m) {
my += c->geom.height + cur_gappiv * ie; my += c->geom.height + cur_gappiv * ie;
} else { } else {
r = n - i; r = n - i;
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
h = slave_surplus_height * c->stack_innder_per / h = slave_surplus_height * c->stack_inner_per /
slave_surplus_ratio; slave_surplus_ratio;
slave_surplus_height = slave_surplus_height - h; slave_surplus_height = slave_surplus_height - h;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
h = (m->w.height - ty - cur_gappov - h = (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)) / cur_gappiv * ie * (r - 1)) /
r; r;
c->stack_innder_per = h / (m->w.height - ty - cur_gappov - c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)); cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} }
// wlr_log(WLR_ERROR, "stack_innder_per: %f", c->stack_innder_per); // wlr_log(WLR_ERROR, "stack_inner_per: %f", c->stack_inner_per);
resize(c, resize(c,
(struct wlr_box){.x = m->w.x + mw + cur_gappoh, (struct wlr_box){.x = m->w.x + mw + cur_gappoh,
@@ -995,22 +995,22 @@ void right_tile(Monitor *m) {
my += c->geom.height + cur_gappiv * ie; my += c->geom.height + cur_gappiv * ie;
} else { } else {
r = n - i; r = n - i;
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
h = slave_surplus_height * c->stack_innder_per / h = slave_surplus_height * c->stack_inner_per /
slave_surplus_ratio; slave_surplus_ratio;
slave_surplus_height = slave_surplus_height - h; slave_surplus_height = slave_surplus_height - h;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
h = (m->w.height - ty - cur_gappov - h = (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)) / cur_gappiv * ie * (r - 1)) /
r; r;
c->stack_innder_per = h / (m->w.height - ty - cur_gappov - c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)); cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} }
// wlr_log(WLR_ERROR, "stack_innder_per: %f", c->stack_innder_per); // wlr_log(WLR_ERROR, "stack_inner_per: %f", c->stack_inner_per);
resize(c, resize(c,
(struct wlr_box){.x = m->w.x + cur_gappoh, (struct wlr_box){.x = m->w.x + cur_gappoh,
@@ -1047,3 +1047,14 @@ monocle(Monitor *m) {
if ((c = focustop(m))) if ((c = focustop(m)))
wlr_scene_node_raise_to_top(&c->scene->node); wlr_scene_node_raise_to_top(&c->scene->node);
} }
void tgmix(Monitor *m) {
uint32_t n = m->visible_tiling_clients;
if (n <= 3) {
tile(m);
return;
} else {
grid(m);
return;
}
}

View File

@@ -12,6 +12,7 @@ static void vertical_grid(Monitor *m);
static void vertical_scroller(Monitor *m); static void vertical_scroller(Monitor *m);
static void vertical_deck(Monitor *mon); static void vertical_deck(Monitor *mon);
static void dual_scroller(Monitor *mon); static void dual_scroller(Monitor *mon);
static void tgmix(Monitor *m);
/* layout(s) */ /* layout(s) */
Layout overviewlayout = {"󰃇", overview, "overview"}; Layout overviewlayout = {"󰃇", overview, "overview"};
@@ -29,6 +30,7 @@ enum {
VERTICAL_DECK, VERTICAL_DECK,
RIGHT_TILE, RIGHT_TILE,
DUAL_SCROLLER, DUAL_SCROLLER,
TGMIX,
}; };
Layout layouts[] = { Layout layouts[] = {
@@ -47,4 +49,5 @@ Layout layouts[] = {
{"VG", vertical_grid, "vertical_grid", VERTICAL_GRID}, // 垂直格子布局 {"VG", vertical_grid, "vertical_grid", VERTICAL_GRID}, // 垂直格子布局
{"VK", vertical_deck, "vertical_deck", VERTICAL_DECK}, // 垂直卡片布局 {"VK", vertical_deck, "vertical_deck", VERTICAL_DECK}, // 垂直卡片布局
{"DS", dual_scroller, "dual_scroller", DUAL_SCROLLER}, // 双行滚动布局 {"DS", dual_scroller, "dual_scroller", DUAL_SCROLLER}, // 双行滚动布局
{"TG", tgmix, "tgmix", TGMIX}, // 混合布局
}; };

View File

@@ -78,17 +78,17 @@ void vertical_tile(Monitor *m) {
mx += c->geom.width + cur_gapih * ie; mx += c->geom.width + cur_gapih * ie;
} else { } else {
r = n - i; r = n - i;
if (c->stack_innder_per > 0.0f) { if (c->stack_inner_per > 0.0f) {
w = slave_surplus_width * c->stack_innder_per / w = slave_surplus_width * c->stack_inner_per /
slave_surplus_ratio; slave_surplus_ratio;
slave_surplus_width = slave_surplus_width - w; slave_surplus_width = slave_surplus_width - w;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} else { } else {
w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) / w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) /
r; r;
c->stack_innder_per = w / (m->w.width - tx - cur_gapih - c->stack_inner_per = w / (m->w.width - tx - cur_gapih -
cur_gapih * ie * (r - 1)); cur_gapih * ie * (r - 1));
c->master_mfact_per = mfact; c->master_mfact_per = mfact;
} }

View File

@@ -165,7 +165,7 @@ enum {
}; /* EWMH atoms */ }; /* EWMH atoms */
#endif #endif
enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* smartmovewin */ enum { UP, DOWN, LEFT, RIGHT, UNDIR }; /* smartmovewin */
enum { NONE, OPEN, MOVE, CLOSE, TAG, FOCUS }; enum { NONE, OPEN, MOVE, CLOSE, TAG, FOCUS, OPAFADEIN, OPAFADEOUT };
enum { UNFOLD, FOLD, INVALIDFOLD }; enum { UNFOLD, FOLD, INVALIDFOLD };
enum { PREV, NEXT }; enum { PREV, NEXT };
enum { STATE_UNSPECIFIED = 0, STATE_ENABLED, STATE_DISABLED }; enum { STATE_UNSPECIFIED = 0, STATE_ENABLED, STATE_DISABLED };
@@ -364,6 +364,7 @@ struct Client {
int isglobal; int isglobal;
int isnoborder; int isnoborder;
int isnoshadow; int isnoshadow;
int isnoradius;
int isnoanimation; int isnoanimation;
int isopensilent; int isopensilent;
int istagsilent; int istagsilent;
@@ -394,8 +395,8 @@ struct Client {
float unfocused_opacity; float unfocused_opacity;
char oldmonname[128]; char oldmonname[128];
int noblur; int noblur;
double master_mfact_per, master_inner_per, stack_innder_per; double master_mfact_per, master_inner_per, stack_inner_per;
double old_master_mfact_per, old_master_inner_per, old_stack_innder_per; double old_master_mfact_per, old_master_inner_per, old_stack_inner_per;
double old_scroller_pproportion; double old_scroller_pproportion;
bool ismaster; bool ismaster;
int dual_scroller_row; // 0 = top row, 1 = bottom row, -1 = not set int dual_scroller_row; // 0 = top row, 1 = bottom row, -1 = not set
@@ -509,7 +510,6 @@ struct Monitor {
uint32_t visible_clients; uint32_t visible_clients;
uint32_t visible_tiling_clients; uint32_t visible_tiling_clients;
uint32_t visible_scroll_tiling_clients; uint32_t visible_scroll_tiling_clients;
bool has_visible_fullscreen_client;
struct wlr_scene_optimized_blur *blur; struct wlr_scene_optimized_blur *blur;
char last_surface_ws_name[256]; char last_surface_ws_name[256];
struct wlr_ext_workspace_group_handle_v1 *ext_group; struct wlr_ext_workspace_group_handle_v1 *ext_group;
@@ -852,6 +852,8 @@ struct dvec2 *baked_points_open;
struct dvec2 *baked_points_tag; struct dvec2 *baked_points_tag;
struct dvec2 *baked_points_close; struct dvec2 *baked_points_close;
struct dvec2 *baked_points_focus; struct dvec2 *baked_points_focus;
struct dvec2 *baked_points_opafadein;
struct dvec2 *baked_points_opafadeout;
static struct wl_event_source *hide_source; static struct wl_event_source *hide_source;
static bool cursor_hidden = false; static bool cursor_hidden = false;
@@ -1215,6 +1217,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) {
APPLY_INT_PROP(c, r, isfullscreen); APPLY_INT_PROP(c, r, isfullscreen);
APPLY_INT_PROP(c, r, isnoborder); APPLY_INT_PROP(c, r, isnoborder);
APPLY_INT_PROP(c, r, isnoshadow); APPLY_INT_PROP(c, r, isnoshadow);
APPLY_INT_PROP(c, r, isnoradius);
APPLY_INT_PROP(c, r, isnoanimation); APPLY_INT_PROP(c, r, isnoanimation);
APPLY_INT_PROP(c, r, isopensilent); APPLY_INT_PROP(c, r, isopensilent);
APPLY_INT_PROP(c, r, istagsilent); APPLY_INT_PROP(c, r, istagsilent);
@@ -1393,8 +1396,11 @@ void applyrules(Client *c) {
// if no geom rule hit and is normal winodw, use the center pos and record // if no geom rule hit and is normal winodw, use the center pos and record
// the hit size // the hit size
if (!hit_rule_pos && (!client_is_x11(c) || !client_is_x11_popup(c))) { if (!hit_rule_pos &&
(!client_is_x11(c) || (c->geom.x == 0 && c->geom.y == 0))) {
c->float_geom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); c->float_geom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0);
} else {
c->float_geom = c->geom;
} }
/*-----------------------apply rule action-------------------------*/ /*-----------------------apply rule action-------------------------*/
@@ -1712,10 +1718,11 @@ axisnotify(struct wl_listener *listener, void *data) {
* implemented checking the event's orientation and the delta of the event * implemented checking the event's orientation and the delta of the event
*/ */
/* Notify the client with pointer focus of the axis event. */ /* Notify the client with pointer focus of the axis event. */
wlr_seat_pointer_notify_axis(seat, // 滚轮事件发送给客户端也就是窗口 wlr_seat_pointer_notify_axis(
event->time_msec, event->orientation, seat, // 滚轮事件发送给客户端也就是窗口
event->delta, event->delta_discrete, event->time_msec, event->orientation, event->delta * axis_scroll_factor,
event->source, event->relative_direction); roundf(event->delta_discrete * axis_scroll_factor), event->source,
event->relative_direction);
} }
int ongesture(struct wlr_pointer_swipe_end_event *event) { int ongesture(struct wlr_pointer_swipe_end_event *event) {
@@ -2001,16 +2008,27 @@ buttonpress(struct wl_listener *listener, void *data) {
} }
void checkidleinhibitor(struct wlr_surface *exclude) { void checkidleinhibitor(struct wlr_surface *exclude) {
int inhibited = 0, unused_lx, unused_ly; int inhibited = 0;
Client *c = NULL;
struct wlr_surface *surface = NULL;
struct wlr_idle_inhibitor_v1 *inhibitor; struct wlr_idle_inhibitor_v1 *inhibitor;
wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) { wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
struct wlr_surface *surface = surface = wlr_surface_get_root_surface(inhibitor->surface);
wlr_surface_get_root_surface(inhibitor->surface);
if (exclude == surface) {
continue;
}
toplevel_from_wlr_surface(inhibitor->surface, &c, NULL);
if (idleinhibit_ignore_visible) {
inhibited = 1;
break;
}
struct wlr_scene_tree *tree = surface->data; struct wlr_scene_tree *tree = surface->data;
if (exclude != surface && if (!tree || (tree->node.enabled && (!c || !c->animation.tagouting))) {
(inhibit_regardless_of_visibility ||
(!tree ||
wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) {
inhibited = 1; inhibited = 1;
break; break;
} }
@@ -3436,13 +3454,13 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
keycode == k->keysymcode.keycode.keycode3))) && keycode == k->keysymcode.keycode.keycode3))) &&
k->func) { k->func) {
isbreak = k->func(&k->arg);
if (!k->ispassapply) if (!k->ispassapply)
handled = 1; handled = 1;
else else
handled = 0; handled = 0;
isbreak = k->func(&k->arg);
if (isbreak) if (isbreak)
break; break;
} }
@@ -3708,18 +3726,24 @@ void init_client_properties(Client *c) {
c->no_force_center = 0; c->no_force_center = 0;
c->isnoborder = 0; c->isnoborder = 0;
c->isnosizehint = 0; c->isnosizehint = 0;
c->isnoradius = 0;
c->isnoshadow = 0;
c->ignore_maximize = 1; c->ignore_maximize = 1;
c->ignore_minimize = 1; c->ignore_minimize = 1;
c->iscustomsize = 0; c->iscustomsize = 0;
c->master_mfact_per = 0.0f; c->master_mfact_per = 0.0f;
c->master_inner_per = 0.0f; c->master_inner_per = 0.0f;
c->stack_innder_per = 0.0f; c->stack_inner_per = 0.0f;
c->isterm = 0; c->isterm = 0;
c->allow_csd = 0; c->allow_csd = 0;
c->force_maximize = 0; c->force_maximize = 0;
c->force_tearing = 0; c->force_tearing = 0;
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
c->scroller_proportion_single = 0.0f; c->scroller_proportion_single = 0.0f;
c->float_geom.width = 0;
c->float_geom.height = 0;
c->float_geom.x = 0;
c->float_geom.y = 0;
} }
void // old fix to 0.5 void // old fix to 0.5
@@ -4023,7 +4047,11 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
.y = grabc->geom.y, .y = grabc->geom.y,
.width = (int)round(cursor->x) - grabc->geom.x, .width = (int)round(cursor->x) - grabc->geom.x,
.height = (int)round(cursor->y) - grabc->geom.y}; .height = (int)round(cursor->y) - grabc->geom.y};
resize(grabc, grabc->float_geom, 1); if (last_apply_drap_time == 0 ||
time - last_apply_drap_time > drag_refresh_interval) {
resize(grabc, grabc->float_geom, 1);
last_apply_drap_time = time;
}
return; return;
} else { } else {
resize_tile_client(grabc, true, 0, 0, time); resize_tile_client(grabc, true, 0, 0, time);
@@ -4319,7 +4347,7 @@ void exchange_two_client(Client *c1, Client *c2) {
uint32_t tmp_tags; uint32_t tmp_tags;
double master_inner_per = 0.0f; double master_inner_per = 0.0f;
double master_mfact_per = 0.0f; double master_mfact_per = 0.0f;
double stack_innder_per = 0.0f; double stack_inner_per = 0.0f;
if (c1 == NULL || c2 == NULL || if (c1 == NULL || c2 == NULL ||
(!exchange_cross_monitor && c1->mon != c2->mon)) { (!exchange_cross_monitor && c1->mon != c2->mon)) {
@@ -4328,15 +4356,15 @@ void exchange_two_client(Client *c1, Client *c2) {
master_inner_per = c1->master_inner_per; master_inner_per = c1->master_inner_per;
master_mfact_per = c1->master_mfact_per; master_mfact_per = c1->master_mfact_per;
stack_innder_per = c1->stack_innder_per; stack_inner_per = c1->stack_inner_per;
c1->master_inner_per = c2->master_inner_per; c1->master_inner_per = c2->master_inner_per;
c1->master_mfact_per = c2->master_mfact_per; c1->master_mfact_per = c2->master_mfact_per;
c1->stack_innder_per = c2->stack_innder_per; c1->stack_inner_per = c2->stack_inner_per;
c2->master_inner_per = master_inner_per; c2->master_inner_per = master_inner_per;
c2->master_mfact_per = master_mfact_per; c2->master_mfact_per = master_mfact_per;
c2->stack_innder_per = stack_innder_per; c2->stack_inner_per = stack_inner_per;
struct wl_list *tmp1_prev = c1->link.prev; struct wl_list *tmp1_prev = c1->link.prev;
struct wl_list *tmp2_prev = c2->link.prev; struct wl_list *tmp2_prev = c2->link.prev;
@@ -4507,7 +4535,7 @@ setfloating(Client *c, int floating) {
} }
// 重新计算居中的坐标 // 重新计算居中的坐标
if (!client_is_x11(c) || !client_is_x11_popup(c)) if (!client_is_x11(c) || (c->geom.x == 0 && c->geom.y == 0))
target_box = setclient_coordinate_center(c, target_box, 0, 0); target_box = setclient_coordinate_center(c, target_box, 0, 0);
backup_box = c->geom; backup_box = c->geom;
hit = applyrulesgeom(c); hit = applyrulesgeom(c);