Merge branch 'main' into feature/dual-row-scroller
This commit is contained in:
@@ -32,7 +32,7 @@ Scroller Layout
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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_close=0.08,0.92,0,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_structs=20
|
||||
@@ -76,7 +78,7 @@ overviewgappo=30
|
||||
no_border_when_single=0
|
||||
axis_bind_apply_timeout=100
|
||||
focus_on_activate=1
|
||||
inhibit_regardless_of_visibility=0
|
||||
idleinhibit_ignore_visible=0
|
||||
sloppyfocus=1
|
||||
warpcursor=1
|
||||
focus_cross_monitor=0
|
||||
|
||||
64
mangowc.scm
Normal file
64
mangowc.scm
Normal 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
|
||||
@@ -1,5 +1,5 @@
|
||||
project('mango', ['c', 'cpp'],
|
||||
version : '0.10.7',
|
||||
version : '0.10.8',
|
||||
)
|
||||
|
||||
subdir('protocols')
|
||||
|
||||
@@ -13,60 +13,64 @@
|
||||
wayland-scanner,
|
||||
xcbutilwm,
|
||||
xwayland,
|
||||
enableXWayland ? true,
|
||||
meson,
|
||||
ninja,
|
||||
scenefx,
|
||||
wlroots_0_19,
|
||||
libGL,
|
||||
}: let
|
||||
enableXWayland ? true,
|
||||
debug ? false,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = "mango";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit pname;
|
||||
version = "nightly";
|
||||
version = "nightly";
|
||||
|
||||
src = builtins.path {
|
||||
path = ../.;
|
||||
name = "source";
|
||||
};
|
||||
src = builtins.path {
|
||||
path = ../.;
|
||||
name = "source";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
wayland-scanner
|
||||
mesonFlags = [
|
||||
(lib.mesonEnable "xwayland" enableXWayland)
|
||||
(lib.mesonBool "asan" debug)
|
||||
];
|
||||
|
||||
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 =
|
||||
[
|
||||
libinput
|
||||
libxcb
|
||||
libxkbcommon
|
||||
pcre2
|
||||
pixman
|
||||
wayland
|
||||
wayland-protocols
|
||||
wlroots_0_19
|
||||
scenefx
|
||||
libGL
|
||||
]
|
||||
++ lib.optionals enableXWayland [
|
||||
libX11
|
||||
xcbutilwm
|
||||
xwayland
|
||||
];
|
||||
passthru = {
|
||||
providedSessions = ["mango"];
|
||||
};
|
||||
|
||||
passthru = {
|
||||
providedSessions = ["mango"];
|
||||
};
|
||||
|
||||
meta = {
|
||||
mainProgram = "mango";
|
||||
description = "A streamlined but feature-rich Wayland compositor";
|
||||
homepage = "https://github.com/DreamMaoMao/mango";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
maintainers = [];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
||||
meta = {
|
||||
mainProgram = "mango";
|
||||
description = "A streamlined but feature-rich Wayland compositor";
|
||||
homepage = "https://github.com/DreamMaoMao/mango";
|
||||
license = lib.licenses.gpl3Plus;
|
||||
maintainers = [];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -240,8 +240,9 @@ void buffer_set_effect(Client *c, BufferData data) {
|
||||
if (c == grabc)
|
||||
data.should_scale = false;
|
||||
|
||||
if (c->isfullscreen || (no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)) {
|
||||
if (c->isnoradius || c->isfullscreen ||
|
||||
(no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)) {
|
||||
data.corner_location = CORNER_LOCATION_NONE;
|
||||
}
|
||||
|
||||
@@ -354,11 +355,13 @@ void apply_border(Client *c) {
|
||||
return;
|
||||
|
||||
bool hit_no_border = check_hit_no_border(c);
|
||||
enum corner_location current_corner_location =
|
||||
c->isfullscreen || (no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)
|
||||
? CORNER_LOCATION_NONE
|
||||
: CORNER_LOCATION_ALL;
|
||||
enum corner_location current_corner_location;
|
||||
if (c->isfullscreen || (no_radius_when_single && c->mon &&
|
||||
c->mon->visible_tiling_clients == 1)) {
|
||||
current_corner_location = CORNER_LOCATION_NONE;
|
||||
} else {
|
||||
current_corner_location = set_client_corner_location(c);
|
||||
}
|
||||
|
||||
// Handle no-border cases
|
||||
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;
|
||||
double factor = find_animation_curve_at(animation_passed, type);
|
||||
|
||||
uint32_t width = c->animation.initial.width +
|
||||
(c->current.width - c->animation.initial.width) * factor;
|
||||
uint32_t height =
|
||||
@@ -650,7 +654,13 @@ void fadeout_client_animation_next_tick(Client *c) {
|
||||
.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)
|
||||
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->current.height - c->animation.initial.height) * factor;
|
||||
|
||||
uint32_t x = c->animation.initial.x +
|
||||
(c->current.x - c->animation.initial.x) * factor;
|
||||
uint32_t y = c->animation.initial.y +
|
||||
(c->current.y - c->animation.initial.y) * factor;
|
||||
int32_t x = c->animation.initial.x +
|
||||
(c->current.x - c->animation.initial.x) * factor;
|
||||
int32_t y = c->animation.initial.y +
|
||||
(c->current.y - c->animation.initial.y) * factor;
|
||||
|
||||
wlr_scene_node_set_position(&c->scene->node, x, y);
|
||||
c->animation.current = (struct wlr_box){
|
||||
@@ -1109,8 +1119,11 @@ bool client_apply_focus_opacity(Client *c) {
|
||||
? (double)passed_time / (double)c->animation.duration
|
||||
: 1.0;
|
||||
|
||||
double opacity_eased_progress =
|
||||
find_animation_curve_at(linear_progress, OPAFADEIN);
|
||||
|
||||
float percent =
|
||||
animation_fade_in && !c->nofadein ? linear_progress : 1.0;
|
||||
animation_fade_in && !c->nofadein ? opacity_eased_progress : 1.0;
|
||||
float opacity =
|
||||
c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@ struct dvec2 calculate_animation_curve_at(double t, int type) {
|
||||
animation_curve = animation_curve_close;
|
||||
} else if (type == 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 {
|
||||
animation_curve = animation_curve_move;
|
||||
}
|
||||
@@ -32,6 +36,10 @@ void init_baked_points(void) {
|
||||
calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close));
|
||||
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++) {
|
||||
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(
|
||||
(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) {
|
||||
@@ -71,6 +87,10 @@ double find_animation_curve_at(double t, int type) {
|
||||
baked_points = baked_points_close;
|
||||
} else if (type == 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 {
|
||||
baked_points = baked_points_move;
|
||||
}
|
||||
|
||||
@@ -276,7 +276,13 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
|
||||
.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)
|
||||
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 +
|
||||
(l->current.y - l->animation.initial.y) * factor;
|
||||
|
||||
double opacity = MIN(fadein_begin_opacity +
|
||||
animation_passed * (1.0 - fadein_begin_opacity),
|
||||
1.0f);
|
||||
double opacity_eased_progress =
|
||||
find_animation_curve_at(animation_passed, OPAFADEIN);
|
||||
|
||||
double opacity =
|
||||
MIN(fadein_begin_opacity +
|
||||
opacity_eased_progress * (1.0 - fadein_begin_opacity),
|
||||
1.0f);
|
||||
|
||||
if (animation_fade_in)
|
||||
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef struct {
|
||||
const char *layer_animation_type_close;
|
||||
int isnoborder;
|
||||
int isnoshadow;
|
||||
int isnoradius;
|
||||
int isnoanimation;
|
||||
int isopensilent;
|
||||
int istagsilent;
|
||||
@@ -194,6 +195,8 @@ typedef struct {
|
||||
double animation_curve_tag[4];
|
||||
double animation_curve_close[4];
|
||||
double animation_curve_focus[4];
|
||||
double animation_curve_opafadein[4];
|
||||
double animation_curve_opafadeout[4];
|
||||
|
||||
int scroller_structs;
|
||||
float scroller_default_proportion;
|
||||
@@ -237,7 +240,7 @@ typedef struct {
|
||||
|
||||
uint32_t axis_bind_apply_timeout;
|
||||
uint32_t focus_on_activate;
|
||||
int inhibit_regardless_of_visibility;
|
||||
int idleinhibit_ignore_visible;
|
||||
int sloppyfocus;
|
||||
int warpcursor;
|
||||
|
||||
@@ -264,6 +267,8 @@ typedef struct {
|
||||
uint32_t send_events_mode;
|
||||
uint32_t button_map;
|
||||
|
||||
double axis_scroll_factor;
|
||||
|
||||
int blur;
|
||||
int blur_layer;
|
||||
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",
|
||||
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) {
|
||||
config->scroller_structs = atoi(value);
|
||||
} 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);
|
||||
} else if (strcmp(key, "numlockon") == 0) {
|
||||
config->numlockon = atoi(value);
|
||||
} else if (strcmp(key, "inhibit_regardless_of_visibility") == 0) {
|
||||
config->inhibit_regardless_of_visibility = atoi(value);
|
||||
} else if (strcmp(key, "idleinhibit_ignore_visible") == 0) {
|
||||
config->idleinhibit_ignore_visible = atoi(value);
|
||||
} else if (strcmp(key, "sloppyfocus") == 0) {
|
||||
config->sloppyfocus = atoi(value);
|
||||
} 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);
|
||||
} else if (strcmp(key, "button_map") == 0) {
|
||||
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) {
|
||||
config->gappih = atoi(value);
|
||||
} else if (strcmp(key, "gappiv") == 0) {
|
||||
@@ -1691,6 +1714,7 @@ void parse_option(Config *config, char *key, char *value) {
|
||||
rule->isfullscreen = -1;
|
||||
rule->isnoborder = -1;
|
||||
rule->isnoshadow = -1;
|
||||
rule->isnoradius = -1;
|
||||
rule->isnoanimation = -1;
|
||||
rule->isopensilent = -1;
|
||||
rule->istagsilent = -1;
|
||||
@@ -1780,6 +1804,8 @@ void parse_option(Config *config, char *key, char *value) {
|
||||
rule->isnoborder = atoi(val);
|
||||
} else if (strcmp(key, "isnoshadow") == 0) {
|
||||
rule->isnoshadow = atoi(val);
|
||||
} else if (strcmp(key, "isnoradius") == 0) {
|
||||
rule->isnoradius = atoi(val);
|
||||
} else if (strcmp(key, "isnoanimation") == 0) {
|
||||
rule->isnoanimation = atoi(val);
|
||||
} else if (strcmp(key, "isopensilent") == 0) {
|
||||
@@ -2406,6 +2432,14 @@ void free_baked_points(void) {
|
||||
free(baked_points_focus);
|
||||
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) {
|
||||
@@ -2719,8 +2753,8 @@ void override_config(void) {
|
||||
axis_bind_apply_timeout =
|
||||
CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000);
|
||||
focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1);
|
||||
inhibit_regardless_of_visibility =
|
||||
CLAMP_INT(config.inhibit_regardless_of_visibility, 0, 1);
|
||||
idleinhibit_ignore_visible =
|
||||
CLAMP_INT(config.idleinhibit_ignore_visible, 0, 1);
|
||||
sloppyfocus = CLAMP_INT(config.sloppyfocus, 0, 1);
|
||||
warpcursor = CLAMP_INT(config.warpcursor, 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);
|
||||
send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2);
|
||||
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);
|
||||
@@ -2820,6 +2855,10 @@ void override_config(void) {
|
||||
sizeof(animation_curve_close));
|
||||
memcpy(animation_curve_focus, config.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() {
|
||||
@@ -2888,6 +2927,7 @@ void set_value_default() {
|
||||
config.exchange_cross_monitor = exchange_cross_monitor;
|
||||
config.scratchpad_cross_monitor = scratchpad_cross_monitor;
|
||||
config.focus_cross_tag = focus_cross_tag;
|
||||
config.axis_scroll_factor = axis_scroll_factor;
|
||||
config.view_current_to_back = view_current_to_back;
|
||||
config.single_scratchpad = single_scratchpad;
|
||||
config.xwayland_persistence = xwayland_persistence;
|
||||
@@ -2903,8 +2943,8 @@ void set_value_default() {
|
||||
config.enable_floating_snap = enable_floating_snap;
|
||||
config.swipe_min_threshold = swipe_min_threshold;
|
||||
|
||||
config.inhibit_regardless_of_visibility =
|
||||
inhibit_regardless_of_visibility; /* 1 means idle inhibitors will
|
||||
config.idleinhibit_ignore_visible =
|
||||
idleinhibit_ignore_visible; /* 1 means idle inhibitors will
|
||||
disable idle tracking even if it's
|
||||
surface isn't visible
|
||||
*/
|
||||
@@ -2969,6 +3009,10 @@ void set_value_default() {
|
||||
sizeof(animation_curve_close));
|
||||
memcpy(config.animation_curve_focus, 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.bordercolor, bordercolor, sizeof(bordercolor));
|
||||
@@ -3171,9 +3215,37 @@ void reapply_monitor_rules(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);
|
||||
cursor_mgr = NULL;
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -3293,5 +3365,5 @@ int reload_config(const Arg *arg) {
|
||||
parse_config();
|
||||
reset_option();
|
||||
printstatus();
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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_close = 300; // Animation close 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_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_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_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_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_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 */
|
||||
uint32_t axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔
|
||||
@@ -79,7 +81,7 @@ uint32_t cursor_hide_timeout = 0;
|
||||
|
||||
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
|
||||
surface isn't visible */
|
||||
uint32_t borderpx = 4; /* border pixel of windows */
|
||||
@@ -105,7 +107,7 @@ int xwayland_persistence = 1; /* xwayland persistence */
|
||||
int syncobj_enable = 0;
|
||||
int adaptive_sync = 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_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||
|
||||
@@ -177,6 +179,8 @@ LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||
enum libinput_config_click_method click_method =
|
||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
|
||||
double axis_scroll_factor = 1.0;
|
||||
|
||||
/* You can choose between:
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
|
||||
|
||||
@@ -196,15 +196,17 @@ int toggle_trackpad_enable(const Arg *arg) {
|
||||
int focusmon(const Arg *arg) {
|
||||
Client *c = NULL;
|
||||
Monitor *m = NULL;
|
||||
Monitor *tm = NULL;
|
||||
|
||||
if (arg->i != UNDIR) {
|
||||
m = dirtomon(arg->i);
|
||||
tm = dirtomon(arg->i);
|
||||
} else if (arg->v) {
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (!m->wlr_output->enabled) {
|
||||
continue;
|
||||
}
|
||||
if (regex_match(arg->v, m->wlr_output->name)) {
|
||||
tm = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -212,10 +214,10 @@ int focusmon(const Arg *arg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m || !m->wlr_output->enabled || m == selmon)
|
||||
if (!tm || !tm->wlr_output->enabled || tm == selmon)
|
||||
return 0;
|
||||
|
||||
selmon = m;
|
||||
selmon = tm;
|
||||
if (warpcursor) {
|
||||
warp_cursor_to_selmon(selmon);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "wlr_ext_workspace_v1.h"
|
||||
|
||||
#define EXT_WORKSPACE_ENABLE_CAPS \
|
||||
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ACTIVATE | \
|
||||
WLR_EXT_WORKSPACE_HANDLE_V1_CAP_DEACTIVATE
|
||||
EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE | \
|
||||
EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_DEACTIVATE
|
||||
|
||||
typedef struct Monitor Monitor;
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ struct wlr_ext_workspace_v1_request {
|
||||
// ACTIVATE / DEACTIVATE / ASSIGN / REMOVE
|
||||
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 {
|
||||
@@ -41,33 +41,40 @@ struct wlr_ext_workspace_v1_group_output {
|
||||
};
|
||||
|
||||
// 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 wlr_ext_workspace_manager_v1 *manager;
|
||||
struct wl_list requests; // wlr_ext_workspace_v1_request.link
|
||||
struct wl_list link; // wlr_ext_workspace_manager_v1.clients
|
||||
struct wl_list requests; // wlr_ext_workspace_v1_request.link
|
||||
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 wlr_ext_workspace_group_handle_v1 *group;
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager;
|
||||
struct wl_list link; // wlr_ext_workspace_group_v1.clients
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager;
|
||||
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 wlr_ext_workspace_handle_v1 *workspace;
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager;
|
||||
struct wl_list link; // wlr_ext_workspace_v1.clients
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager;
|
||||
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 struct wlr_ext_workspace_group_client_v1 *
|
||||
group_client_from_resource(struct wl_resource *resource) {
|
||||
static struct wlr_ext_workspace_group_v1_resource *
|
||||
group_resource_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(
|
||||
resource, &ext_workspace_group_handle_v1_interface, &group_impl));
|
||||
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 struct wlr_ext_workspace_client_v1 *
|
||||
workspace_client_from_resource(struct wl_resource *resource) {
|
||||
static struct wlr_ext_workspace_v1_resource *
|
||||
workspace_resource_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface,
|
||||
&workspace_impl));
|
||||
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 struct wlr_ext_workspace_manager_client_v1 *
|
||||
manager_client_from_resource(struct wl_resource *resource) {
|
||||
static struct wlr_ext_workspace_manager_v1_resource *
|
||||
manager_resource_from_resource(struct wl_resource *resource) {
|
||||
assert(wl_resource_instance_of(
|
||||
resource, &ext_workspace_manager_v1_interface, &manager_impl));
|
||||
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,
|
||||
struct wl_resource *workspace_resource) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace =
|
||||
workspace_client_from_resource(workspace_resource);
|
||||
if (!workspace) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
workspace_resource_from_resource(workspace_resource);
|
||||
if (!workspace_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,16 +117,16 @@ static void workspace_handle_activate(struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE;
|
||||
req->workspace = workspace->workspace;
|
||||
wl_list_insert(workspace->manager->requests.prev, &req->link);
|
||||
req->workspace = workspace_res->workspace;
|
||||
wl_list_insert(workspace_res->manager->requests.prev, &req->link);
|
||||
}
|
||||
|
||||
static void
|
||||
workspace_handle_deactivate(struct wl_client *client,
|
||||
struct wl_resource *workspace_resource) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace =
|
||||
workspace_client_from_resource(workspace_resource);
|
||||
if (!workspace) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
workspace_resource_from_resource(workspace_resource);
|
||||
if (!workspace_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -129,18 +136,18 @@ workspace_handle_deactivate(struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE;
|
||||
req->workspace = workspace->workspace;
|
||||
wl_list_insert(workspace->manager->requests.prev, &req->link);
|
||||
req->workspace = workspace_res->workspace;
|
||||
wl_list_insert(workspace_res->manager->requests.prev, &req->link);
|
||||
}
|
||||
|
||||
static void workspace_handle_assign(struct wl_client *client,
|
||||
struct wl_resource *workspace_resource,
|
||||
struct wl_resource *group_resource) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace =
|
||||
workspace_client_from_resource(workspace_resource);
|
||||
struct wlr_ext_workspace_group_client_v1 *group =
|
||||
group_client_from_resource(group_resource);
|
||||
if (!workspace || !group) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
workspace_resource_from_resource(workspace_resource);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
group_resource_from_resource(group_resource);
|
||||
if (!workspace_res || !group_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -150,16 +157,16 @@ static void workspace_handle_assign(struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN;
|
||||
req->group = group->group;
|
||||
req->workspace = workspace->workspace;
|
||||
wl_list_insert(workspace->manager->requests.prev, &req->link);
|
||||
req->group = group_res->group;
|
||||
req->workspace = workspace_res->workspace;
|
||||
wl_list_insert(workspace_res->manager->requests.prev, &req->link);
|
||||
}
|
||||
|
||||
static void workspace_handle_remove(struct wl_client *client,
|
||||
struct wl_resource *workspace_resource) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace =
|
||||
workspace_client_from_resource(workspace_resource);
|
||||
if (!workspace) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
workspace_resource_from_resource(workspace_resource);
|
||||
if (!workspace_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -169,8 +176,8 @@ static void workspace_handle_remove(struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
req->type = WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE;
|
||||
req->workspace = workspace->workspace;
|
||||
wl_list_insert(workspace->manager->requests.prev, &req->link);
|
||||
req->workspace = workspace_res->workspace;
|
||||
wl_list_insert(workspace_res->manager->requests.prev, &req->link);
|
||||
}
|
||||
|
||||
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,
|
||||
struct wl_resource *group_resource,
|
||||
const char *name) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group =
|
||||
group_client_from_resource(group_resource);
|
||||
if (!group) {
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
group_resource_from_resource(group_resource);
|
||||
if (!group_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,9 +202,15 @@ static void group_handle_create_workspace(struct wl_client *client,
|
||||
wl_resource_post_no_memory(group_resource);
|
||||
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->group = group->group;
|
||||
wl_list_insert(group->manager->requests.prev, &req->link);
|
||||
req->group = group_res->group;
|
||||
wl_list_insert(group_res->manager->requests.prev, &req->link);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_workspace_client(struct wlr_ext_workspace_client_v1 *workspace_client) {
|
||||
wl_list_remove(&workspace_client->link);
|
||||
wl_resource_set_user_data(workspace_client->resource, NULL);
|
||||
free(workspace_client);
|
||||
static void destroy_workspace_resource(
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res) {
|
||||
wl_list_remove(&workspace_res->link);
|
||||
wl_list_remove(&workspace_res->manager_resource_link);
|
||||
wl_resource_set_user_data(workspace_res->resource, NULL);
|
||||
free(workspace_res);
|
||||
}
|
||||
|
||||
static void workspace_resource_destroy(struct wl_resource *resource) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client =
|
||||
workspace_client_from_resource(resource);
|
||||
if (workspace_client) {
|
||||
destroy_workspace_client(workspace_client);
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
workspace_resource_from_resource(resource);
|
||||
if (workspace_res) {
|
||||
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_manager_client_v1 *manager_client) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client =
|
||||
calloc(1, sizeof(*workspace_client));
|
||||
if (!workspace_client) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
calloc(1, sizeof(*workspace_res));
|
||||
if (!workspace_res) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wl_client *client = wl_resource_get_client(manager_client->resource);
|
||||
workspace_client->resource = wl_resource_create(
|
||||
client, &ext_workspace_handle_v1_interface,
|
||||
wl_resource_get_version(manager_client->resource), 0);
|
||||
if (!workspace_client->resource) {
|
||||
free(workspace_client);
|
||||
struct wl_client *client = wl_resource_get_client(manager_res->resource);
|
||||
workspace_res->resource =
|
||||
wl_resource_create(client, &ext_workspace_handle_v1_interface,
|
||||
wl_resource_get_version(manager_res->resource), 0);
|
||||
if (!workspace_res->resource) {
|
||||
free(workspace_res);
|
||||
return NULL;
|
||||
}
|
||||
wl_resource_set_implementation(workspace_client->resource, &workspace_impl,
|
||||
workspace_client,
|
||||
workspace_resource_destroy);
|
||||
wl_resource_set_implementation(workspace_res->resource, &workspace_impl,
|
||||
workspace_res, workspace_resource_destroy);
|
||||
|
||||
workspace_client->workspace = workspace;
|
||||
workspace_client->manager = manager_client;
|
||||
wl_list_insert(&workspace->clients, &workspace_client->link);
|
||||
workspace_res->workspace = workspace;
|
||||
workspace_res->manager = manager_res;
|
||||
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
|
||||
destroy_group_client(struct wlr_ext_workspace_group_client_v1 *group_client) {
|
||||
wl_list_remove(&group_client->link);
|
||||
wl_resource_set_user_data(group_client->resource, NULL);
|
||||
free(group_client);
|
||||
destroy_group_resource(struct wlr_ext_workspace_group_v1_resource *group_res) {
|
||||
wl_list_remove(&group_res->link);
|
||||
wl_list_remove(&group_res->manager_resource_link);
|
||||
wl_resource_set_user_data(group_res->resource, NULL);
|
||||
free(group_res);
|
||||
}
|
||||
|
||||
static void group_handle_resource_destroy(struct wl_resource *resource) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client =
|
||||
group_client_from_resource(resource);
|
||||
if (group_client) {
|
||||
destroy_group_client(group_client);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
group_resource_from_resource(resource);
|
||||
if (group_res) {
|
||||
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_manager_client_v1 *manager_client) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client =
|
||||
calloc(1, sizeof(*group_client));
|
||||
if (!group_client) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res) {
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
calloc(1, sizeof(*group_res));
|
||||
if (!group_res) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct wl_client *client = wl_resource_get_client(manager_client->resource);
|
||||
uint32_t version = wl_resource_get_version(manager_client->resource);
|
||||
group_client->resource = wl_resource_create(
|
||||
struct wl_client *client = wl_resource_get_client(manager_res->resource);
|
||||
uint32_t version = wl_resource_get_version(manager_res->resource);
|
||||
group_res->resource = wl_resource_create(
|
||||
client, &ext_workspace_group_handle_v1_interface, version, 0);
|
||||
if (group_client->resource == NULL) {
|
||||
free(group_client);
|
||||
if (group_res->resource == NULL) {
|
||||
free(group_res);
|
||||
return NULL;
|
||||
}
|
||||
wl_resource_set_implementation(group_client->resource, &group_impl,
|
||||
group_client, group_handle_resource_destroy);
|
||||
wl_resource_set_implementation(group_res->resource, &group_impl, group_res,
|
||||
group_handle_resource_destroy);
|
||||
|
||||
group_client->group = group;
|
||||
group_client->manager = manager_client;
|
||||
wl_list_insert(&group->clients, &group_client->link);
|
||||
group_res->group = group;
|
||||
group_res->manager = manager_res;
|
||||
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) {
|
||||
@@ -303,18 +321,22 @@ static void destroy_request(struct wlr_ext_workspace_v1_request *req) {
|
||||
|
||||
static void manager_handle_commit(struct wl_client *client,
|
||||
struct wl_resource *resource) {
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager =
|
||||
manager_client_from_resource(resource);
|
||||
if (!manager) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res =
|
||||
manager_resource_from_resource(resource);
|
||||
if (!manager_res) {
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
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,
|
||||
req->name);
|
||||
&event);
|
||||
break;
|
||||
case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE:
|
||||
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);
|
||||
break;
|
||||
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;
|
||||
case WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE:
|
||||
wl_signal_emit_mutable(&req->workspace->events.remove, NULL);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
destroy_request(req);
|
||||
}
|
||||
@@ -338,9 +358,9 @@ static void manager_handle_commit(struct wl_client *client,
|
||||
static void handle_idle(void *data) {
|
||||
struct wlr_ext_workspace_manager_v1 *manager = data;
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client;
|
||||
wl_list_for_each(manager_client, &manager->clients, link) {
|
||||
ext_workspace_manager_v1_send_done(manager_client->resource);
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res;
|
||||
wl_list_for_each(manager_res, &manager->resources, link) {
|
||||
ext_workspace_manager_v1_send_done(manager_res->resource);
|
||||
}
|
||||
manager->idle_source = NULL;
|
||||
}
|
||||
@@ -354,9 +374,9 @@ manager_schedule_done(struct wlr_ext_workspace_manager_v1 *manager) {
|
||||
}
|
||||
|
||||
static void
|
||||
workspace_send_details(struct wlr_ext_workspace_client_v1 *workspace_client) {
|
||||
struct wlr_ext_workspace_handle_v1 *workspace = workspace_client->workspace;
|
||||
struct wl_resource *resource = workspace_client->resource;
|
||||
workspace_send_details(struct wlr_ext_workspace_v1_resource *workspace_res) {
|
||||
struct wlr_ext_workspace_handle_v1 *workspace = workspace_res->workspace;
|
||||
struct wl_resource *resource = workspace_res->resource;
|
||||
|
||||
ext_workspace_handle_v1_send_capabilities(resource, workspace->caps);
|
||||
if (workspace->coordinates.size > 0) {
|
||||
@@ -384,29 +404,41 @@ static const struct ext_workspace_manager_v1_interface manager_impl = {
|
||||
.stop = manager_handle_stop,
|
||||
};
|
||||
|
||||
static void destroy_manager_client(
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client) {
|
||||
static void destroy_manager_resource(
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res) {
|
||||
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);
|
||||
}
|
||||
wl_list_remove(&manager_client->link);
|
||||
wl_resource_set_user_data(manager_client->resource, NULL);
|
||||
free(manager_client);
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res, *tmp2;
|
||||
wl_list_for_each_safe(workspace_res, tmp2,
|
||||
&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) {
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client =
|
||||
manager_client_from_resource(resource);
|
||||
if (manager_client) {
|
||||
destroy_manager_client(manager_client);
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res =
|
||||
manager_resource_from_resource(resource);
|
||||
if (manager_res) {
|
||||
destroy_manager_resource(manager_res);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
group_send_details(struct wlr_ext_workspace_group_client_v1 *group_client) {
|
||||
struct wlr_ext_workspace_group_handle_v1 *group = group_client->group;
|
||||
struct wl_resource *resource = group_client->resource;
|
||||
group_send_details(struct wlr_ext_workspace_group_v1_resource *group_res) {
|
||||
struct wlr_ext_workspace_group_handle_v1 *group = group_res->group;
|
||||
struct wl_resource *resource = group_res->resource;
|
||||
struct wl_client *client = wl_resource_get_client(resource);
|
||||
|
||||
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) {
|
||||
struct wlr_ext_workspace_manager_v1 *manager = data;
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client =
|
||||
calloc(1, sizeof(*manager_client));
|
||||
if (!manager_client) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res =
|
||||
calloc(1, sizeof(*manager_res));
|
||||
if (!manager_res) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
manager_client->manager = manager;
|
||||
wl_list_init(&manager_client->requests);
|
||||
wl_list_insert(&manager->clients, &manager_client->link);
|
||||
manager_res->manager = manager;
|
||||
wl_list_init(&manager_res->requests);
|
||||
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);
|
||||
if (!manager_client->resource) {
|
||||
free(manager_client);
|
||||
if (!manager_res->resource) {
|
||||
free(manager_res);
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
wl_resource_set_implementation(manager_client->resource, &manager_impl,
|
||||
manager_client, manager_resource_destroy);
|
||||
wl_resource_set_implementation(manager_res->resource, &manager_impl,
|
||||
manager_res, manager_resource_destroy);
|
||||
wl_list_insert(&manager->resources, &manager_res->link);
|
||||
|
||||
struct wlr_ext_workspace_group_handle_v1 *group;
|
||||
wl_list_for_each(group, &manager->groups, link) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client =
|
||||
create_group_client(group, manager_client);
|
||||
if (!group_client) {
|
||||
wl_resource_post_no_memory(manager_client->resource);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
create_group_resource(group, manager_res);
|
||||
if (!group_res) {
|
||||
wl_resource_post_no_memory(manager_res->resource);
|
||||
continue;
|
||||
}
|
||||
ext_workspace_manager_v1_send_workspace_group(manager_client->resource,
|
||||
group_client->resource);
|
||||
group_send_details(group_client);
|
||||
ext_workspace_manager_v1_send_workspace_group(manager_res->resource,
|
||||
group_res->resource);
|
||||
group_send_details(group_res);
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_handle_v1 *workspace;
|
||||
wl_list_for_each(workspace, &manager->workspaces, link) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client =
|
||||
create_workspace_client(workspace, manager_client);
|
||||
if (!workspace) {
|
||||
wl_client_post_no_memory(client);
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
create_workspace_resource(workspace, manager_res);
|
||||
if (!workspace_res) {
|
||||
wl_resource_post_no_memory(manager_res->resource);
|
||||
continue;
|
||||
}
|
||||
ext_workspace_manager_v1_send_workspace(manager_client->resource,
|
||||
workspace_client->resource);
|
||||
workspace_send_details(workspace_client);
|
||||
ext_workspace_manager_v1_send_workspace(manager_res->resource,
|
||||
workspace_res->resource);
|
||||
workspace_send_details(workspace_res);
|
||||
|
||||
if (!workspace->group) {
|
||||
continue;
|
||||
}
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client;
|
||||
wl_list_for_each(group_client, &workspace->group->clients, link) {
|
||||
if (group_client->manager == manager_client) {
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res;
|
||||
wl_list_for_each(group_res, &workspace->group->resources, link) {
|
||||
if (group_res->manager == manager_res) {
|
||||
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,
|
||||
@@ -509,9 +543,9 @@ static void manager_handle_display_destroy(struct wl_listener *listener,
|
||||
wlr_ext_workspace_handle_v1_destroy(workspace);
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client, *tmp3;
|
||||
wl_list_for_each_safe(manager_client, tmp3, &manager->clients, link) {
|
||||
destroy_manager_client(manager_client);
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res, *tmp3;
|
||||
wl_list_for_each_safe(manager_res, tmp3, &manager->resources, link) {
|
||||
destroy_manager_resource(manager_res);
|
||||
}
|
||||
|
||||
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->workspaces);
|
||||
wl_list_init(&manager->clients);
|
||||
wl_list_init(&manager->resources);
|
||||
wl_signal_init(&manager->events.destroy);
|
||||
|
||||
return manager;
|
||||
@@ -566,22 +600,22 @@ wlr_ext_workspace_group_handle_v1_create(
|
||||
group->caps = caps;
|
||||
|
||||
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.destroy);
|
||||
|
||||
wl_list_insert(manager->groups.prev, &group->link);
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client;
|
||||
wl_list_for_each(manager_client, &manager->clients, link) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client =
|
||||
create_group_client(group, manager_client);
|
||||
if (!group_client) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res;
|
||||
wl_list_for_each(manager_res, &manager->resources, link) {
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res =
|
||||
create_group_resource(group, manager_res);
|
||||
if (!group_res) {
|
||||
continue;
|
||||
}
|
||||
ext_workspace_manager_v1_send_workspace_group(manager_client->resource,
|
||||
group_client->resource);
|
||||
group_send_details(group_client);
|
||||
ext_workspace_manager_v1_send_workspace_group(manager_res->resource,
|
||||
group_res->resource);
|
||||
group_send_details(group_res);
|
||||
}
|
||||
|
||||
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,
|
||||
bool enter) {
|
||||
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client;
|
||||
wl_list_for_each(workspace_client, &workspace->clients, link) {
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client;
|
||||
wl_list_for_each(group_client, &group->clients, link) {
|
||||
if (group_client->manager != workspace_client->manager) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res;
|
||||
wl_list_for_each(workspace_res, &workspace->resources, link) {
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res;
|
||||
wl_list_for_each(group_res, &group->resources, link) {
|
||||
if (group_res->manager != workspace_res->manager) {
|
||||
continue;
|
||||
}
|
||||
if (enter) {
|
||||
ext_workspace_group_handle_v1_send_workspace_enter(
|
||||
group_client->resource, workspace_client->resource);
|
||||
group_res->resource, workspace_res->resource);
|
||||
} else {
|
||||
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,
|
||||
struct wlr_output *output, bool enter) {
|
||||
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client;
|
||||
wl_list_for_each(group_client, &group->clients, link) {
|
||||
struct wl_client *client =
|
||||
wl_resource_get_client(group_client->resource);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res;
|
||||
wl_list_for_each(group_res, &group->resources, link) {
|
||||
struct wl_client *client = wl_resource_get_client(group_res->resource);
|
||||
|
||||
struct wl_resource *output_resource;
|
||||
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) {
|
||||
ext_workspace_group_handle_v1_send_output_enter(
|
||||
group_client->resource, output_resource);
|
||||
group_res->resource, output_resource);
|
||||
} else {
|
||||
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(
|
||||
struct wlr_ext_workspace_group_handle_v1 *group) {
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&group->events.destroy, NULL);
|
||||
|
||||
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;
|
||||
wl_list_for_each_safe(group_client, tmp, &group->clients, link) {
|
||||
ext_workspace_group_handle_v1_send_removed(group_client->resource);
|
||||
destroy_group_client(group_client);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res, *tmp;
|
||||
wl_list_for_each_safe(group_res, tmp, &group->resources, link) {
|
||||
ext_workspace_group_handle_v1_send_removed(group_res->resource);
|
||||
destroy_group_resource(group_res);
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client;
|
||||
wl_list_for_each(manager_client, &group->manager->clients, link) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res;
|
||||
wl_list_for_each(manager_res, &group->manager->resources, link) {
|
||||
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) {
|
||||
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 wl_client *client = wl_resource_get_client(event->resource);
|
||||
|
||||
struct wlr_ext_workspace_group_client_v1 *group_client;
|
||||
wl_list_for_each(group_client, &group_output->group->clients, link) {
|
||||
if (wl_resource_get_client(group_client->resource) == client) {
|
||||
ext_workspace_group_handle_v1_send_output_enter(
|
||||
group_client->resource, event->resource);
|
||||
struct wlr_ext_workspace_group_v1_resource *group_res;
|
||||
wl_list_for_each(group_res, &group_output->group->resources, link) {
|
||||
if (wl_resource_get_client(group_res->resource) == client) {
|
||||
ext_workspace_group_handle_v1_send_output_enter(group_res->resource,
|
||||
event->resource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,11 +815,12 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager,
|
||||
if (id) {
|
||||
workspace->id = strdup(id);
|
||||
if (!workspace->id) {
|
||||
free(workspace);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wl_list_init(&workspace->clients);
|
||||
wl_list_init(&workspace->resources);
|
||||
wl_array_init(&workspace->coordinates);
|
||||
wl_signal_init(&workspace->events.activate);
|
||||
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);
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client;
|
||||
wl_list_for_each(manager_client, &manager->clients, link) {
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client =
|
||||
create_workspace_client(workspace, manager_client);
|
||||
if (!workspace_client) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res;
|
||||
wl_list_for_each(manager_res, &manager->resources, link) {
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res =
|
||||
create_workspace_resource(workspace, manager_res);
|
||||
if (!workspace_res) {
|
||||
continue;
|
||||
}
|
||||
ext_workspace_manager_v1_send_workspace(manager_client->resource,
|
||||
workspace_client->resource);
|
||||
workspace_send_details(workspace_client);
|
||||
ext_workspace_manager_v1_send_workspace(manager_res->resource,
|
||||
workspace_res->resource);
|
||||
workspace_send_details(workspace_res);
|
||||
}
|
||||
|
||||
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(
|
||||
struct wlr_ext_workspace_handle_v1 *workspace) {
|
||||
if (!workspace) {
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_emit_mutable(&workspace->events.destroy, NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client, *tmp;
|
||||
wl_list_for_each_safe(workspace_client, tmp, &workspace->clients, link) {
|
||||
ext_workspace_handle_v1_send_removed(workspace_client->resource);
|
||||
destroy_workspace_client(workspace_client);
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res, *tmp;
|
||||
wl_list_for_each_safe(workspace_res, tmp, &workspace->resources, link) {
|
||||
ext_workspace_handle_v1_send_removed(workspace_res->resource);
|
||||
destroy_workspace_resource(workspace_res);
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_manager_client_v1 *manager_client;
|
||||
wl_list_for_each(manager_client, &workspace->manager->clients, link) {
|
||||
struct wlr_ext_workspace_manager_v1_resource *manager_res;
|
||||
wl_list_for_each(manager_res, &workspace->manager->resources, link) {
|
||||
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) {
|
||||
destroy_request(req);
|
||||
}
|
||||
@@ -856,7 +898,7 @@ void wlr_ext_workspace_handle_v1_set_group(
|
||||
}
|
||||
|
||||
if (workspace->group) {
|
||||
workspace_send_group(workspace, group, false);
|
||||
workspace_send_group(workspace, workspace->group, false);
|
||||
}
|
||||
workspace->group = group;
|
||||
if (group) {
|
||||
@@ -878,9 +920,9 @@ void wlr_ext_workspace_handle_v1_set_name(
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client;
|
||||
wl_list_for_each(workspace_client, &workspace->clients, link) {
|
||||
ext_workspace_handle_v1_send_name(workspace_client->resource,
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res;
|
||||
wl_list_for_each(workspace_res, &workspace->resources, link) {
|
||||
ext_workspace_handle_v1_send_name(workspace_res->resource,
|
||||
workspace->name);
|
||||
}
|
||||
|
||||
@@ -905,9 +947,9 @@ void wlr_ext_workspace_handle_v1_set_coordinates(
|
||||
wl_array_init(&workspace->coordinates);
|
||||
wl_array_copy(&workspace->coordinates, coordinates);
|
||||
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client;
|
||||
wl_list_for_each(workspace_client, &workspace->clients, link) {
|
||||
ext_workspace_handle_v1_send_coordinates(workspace_client->resource,
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res;
|
||||
wl_list_for_each(workspace_res, &workspace->resources, link) {
|
||||
ext_workspace_handle_v1_send_coordinates(workspace_res->resource,
|
||||
&workspace->coordinates);
|
||||
}
|
||||
|
||||
@@ -927,9 +969,9 @@ static void workspace_set_state(struct wlr_ext_workspace_handle_v1 *workspace,
|
||||
return;
|
||||
}
|
||||
|
||||
struct wlr_ext_workspace_client_v1 *workspace_client;
|
||||
wl_list_for_each(workspace_client, &workspace->clients, link) {
|
||||
ext_workspace_handle_v1_send_state(workspace_client->resource,
|
||||
struct wlr_ext_workspace_v1_resource *workspace_res;
|
||||
wl_list_for_each(workspace_res, &workspace->resources, link) {
|
||||
ext_workspace_handle_v1_send_state(workspace_res->resource,
|
||||
workspace->state);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,32 +2,11 @@
|
||||
// TODO: remove this file
|
||||
// refer: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5115
|
||||
|
||||
/*
|
||||
* 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-protocols/ext-workspace-v1-enum.h>
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
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 wl_global *global;
|
||||
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;
|
||||
} events;
|
||||
|
||||
struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link
|
||||
struct wl_event_source *idle_source;
|
||||
struct wl_event_loop *event_loop;
|
||||
struct wl_listener display_destroy;
|
||||
struct {
|
||||
struct wl_list resources; // wlr_ext_workspace_manager_v1_resource.link
|
||||
struct wl_event_source *idle_source;
|
||||
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_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 wl_signal create_workspace; // const char *
|
||||
struct wl_signal
|
||||
create_workspace; // wlr_ext_workspace_group_handle_v1_create_workspace_event
|
||||
struct wl_signal destroy;
|
||||
} events;
|
||||
|
||||
struct wl_list link; // wlr_ext_workspace_manager_v1.groups
|
||||
|
||||
struct wl_list outputs; // wlr_ext_workspace_v1_group_output.link
|
||||
struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link
|
||||
struct {
|
||||
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 {
|
||||
@@ -63,7 +51,7 @@ struct wlr_ext_workspace_handle_v1 {
|
||||
char *id;
|
||||
char *name;
|
||||
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
|
||||
|
||||
struct {
|
||||
@@ -74,9 +62,11 @@ struct wlr_ext_workspace_handle_v1 {
|
||||
struct wl_signal destroy;
|
||||
} 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 *
|
||||
@@ -114,5 +104,3 @@ void wlr_ext_workspace_handle_v1_set_urgent(
|
||||
struct wlr_ext_workspace_handle_v1 *workspace, bool enabled);
|
||||
void wlr_ext_workspace_handle_v1_set_hidden(
|
||||
struct wlr_ext_workspace_handle_v1 *workspace, bool enabled);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -389,30 +389,21 @@ Client *focustop(Monitor *m) {
|
||||
|
||||
Client *get_next_stack_client(Client *c, bool reverse) {
|
||||
if (!c || !c->mon)
|
||||
return NULL; // 添加输入检查
|
||||
return NULL;
|
||||
|
||||
Client *next = NULL;
|
||||
if (reverse) {
|
||||
wl_list_for_each_reverse(next, &c->link, link) {
|
||||
if (!next)
|
||||
continue; // 安全检查
|
||||
if (&next->link == &clients)
|
||||
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))
|
||||
return next;
|
||||
}
|
||||
} else {
|
||||
wl_list_for_each(next, &c->link, link) {
|
||||
if (!next)
|
||||
continue; // 安全检查
|
||||
|
||||
if (c->mon->has_visible_fullscreen_client && !next->isfloating &&
|
||||
!next->isfullscreen)
|
||||
continue;
|
||||
if (&next->link == &clients)
|
||||
continue; /* wrap past the sentinel node */
|
||||
|
||||
if (next != c && next->mon && VISIBLEON(next, c->mon))
|
||||
return next;
|
||||
|
||||
@@ -5,7 +5,7 @@ void set_size_per(Monitor *m, Client *c) {
|
||||
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
|
||||
c->master_mfact_per = fc->master_mfact_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;
|
||||
break;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ void set_size_per(Monitor *m, Client *c) {
|
||||
if (!found) {
|
||||
c->master_mfact_per = m->pertag->mfacts[m->pertag->curtag];
|
||||
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_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 =
|
||||
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||
grabc->cursor_in_left_half =
|
||||
@@ -86,7 +86,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_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->cursor_in_upper_half = true;
|
||||
grabc->cursor_in_left_half = false;
|
||||
@@ -100,7 +100,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
|
||||
} else {
|
||||
delta_x = (float)(offsetx) * (1 - grabc->old_master_mfact_per) /
|
||||
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;
|
||||
}
|
||||
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_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_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) {
|
||||
@@ -197,7 +197,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
|
||||
}
|
||||
|
||||
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) {
|
||||
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_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 =
|
||||
cursor->y < grabc->geom.y + grabc->geom.height / 2;
|
||||
grabc->cursor_in_left_half =
|
||||
@@ -267,7 +267,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_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->cursor_in_upper_half = true;
|
||||
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) /
|
||||
grabc->drag_begin_geom.height;
|
||||
} else {
|
||||
delta_x = (float)(offsetx) * (grabc->old_stack_innder_per) /
|
||||
delta_x = (float)(offsetx) * (grabc->old_stack_inner_per) /
|
||||
grabc->drag_begin_geom.width;
|
||||
delta_y = (float)(offsety) * (1 - grabc->old_master_mfact_per) /
|
||||
grabc->drag_begin_geom.height;
|
||||
@@ -338,13 +338,13 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
|
||||
delta_y; // 垂直:delta_y调整主区域高度
|
||||
float new_master_inner_per = grabc->old_master_inner_per +
|
||||
delta_x; // 垂直:delta_x调整主区域内部宽度
|
||||
float new_stack_innder_per = grabc->old_stack_innder_per +
|
||||
delta_x; // 垂直:delta_x调整栈区域内部宽度
|
||||
float new_stack_inner_per = grabc->old_stack_inner_per +
|
||||
delta_x; // 垂直:delta_x调整栈区域内部宽度
|
||||
|
||||
// 应用限制,确保比例在合理范围内
|
||||
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_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) {
|
||||
@@ -354,7 +354,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
|
||||
}
|
||||
|
||||
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) {
|
||||
arrange(grabc->mon, false);
|
||||
@@ -402,7 +402,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety,
|
||||
} else {
|
||||
grabc->old_master_mfact_per = grabc->master_mfact_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->old_scroller_pproportion = grabc->scroller_proportion;
|
||||
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 =
|
||||
grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag];
|
||||
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,
|
||||
@@ -520,16 +521,16 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
|
||||
if (VISIBLEON(c, m) && ISTILED(c)) {
|
||||
if (total_master_inner_percent > 0.0 && i < nmasters) {
|
||||
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 / total_master_inner_percent;
|
||||
} else {
|
||||
c->ismaster = false;
|
||||
c->master_inner_per =
|
||||
master_num > 0 ? 1.0f / master_num : 1.0f;
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
total_stack_hight_percent
|
||||
? c->stack_innder_per / total_stack_hight_percent
|
||||
? c->stack_inner_per / total_stack_hight_percent
|
||||
: 1.0f;
|
||||
}
|
||||
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) {
|
||||
c->ismaster = true;
|
||||
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;
|
||||
|
||||
} else {
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
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 =
|
||||
master_num > 0 ? 1.0f / master_num : 1.0f;
|
||||
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
total_right_stack_hight_percent
|
||||
? c->stack_innder_per /
|
||||
? c->stack_inner_per /
|
||||
total_right_stack_hight_percent
|
||||
: 1.0f;
|
||||
} else {
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
total_left_stack_hight_percent
|
||||
? c->stack_innder_per /
|
||||
? c->stack_inner_per /
|
||||
total_left_stack_hight_percent
|
||||
: 1.0f;
|
||||
}
|
||||
@@ -580,7 +581,7 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
|
||||
void // 17
|
||||
arrange(Monitor *m, bool want_animation) {
|
||||
Client *c = NULL;
|
||||
double total_stack_innder_percent = 0;
|
||||
double total_stack_inner_percent = 0;
|
||||
double total_master_inner_percent = 0;
|
||||
double total_right_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_tiling_clients = 0;
|
||||
m->visible_scroll_tiling_clients = 0;
|
||||
m->has_visible_fullscreen_client = false;
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
|
||||
@@ -612,9 +612,6 @@ arrange(Monitor *m, bool want_animation) {
|
||||
if (!c->isunglobal)
|
||||
m->visible_clients++;
|
||||
|
||||
if (c->isfullscreen)
|
||||
m->has_visible_fullscreen_client = true;
|
||||
|
||||
if (ISTILED(c)) {
|
||||
m->visible_tiling_clients++;
|
||||
}
|
||||
@@ -640,17 +637,17 @@ arrange(Monitor *m, bool want_animation) {
|
||||
total_master_inner_percent += c->master_inner_per;
|
||||
} else {
|
||||
stack_num++;
|
||||
total_stack_innder_percent += c->stack_innder_per;
|
||||
total_stack_inner_percent += c->stack_inner_per;
|
||||
stack_index = i - nmasters;
|
||||
if ((stack_index % 2) ^
|
||||
(m->visible_tiling_clients % 2 == 0)) {
|
||||
c->isleftstack = false;
|
||||
total_right_stack_hight_percent +=
|
||||
c->stack_innder_per;
|
||||
c->stack_inner_per;
|
||||
} else {
|
||||
c->isleftstack = true;
|
||||
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(
|
||||
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);
|
||||
|
||||
if (m->isoverview) {
|
||||
|
||||
@@ -705,17 +705,17 @@ void center_tile(Monitor *m) {
|
||||
if (n - nmasters == 1) {
|
||||
// 单个堆叠窗口
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
h = (m->w.height - 2 * cur_gappov -
|
||||
cur_gappiv * ie * (stack_num - 1)) *
|
||||
c->stack_innder_per;
|
||||
c->stack_inner_per;
|
||||
c->master_mfact_per = mfact;
|
||||
} else {
|
||||
h = (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = h / (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->stack_inner_per = h / (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
@@ -741,19 +741,19 @@ void center_tile(Monitor *m) {
|
||||
|
||||
if ((stack_index % 2) ^ (n % 2 == 0)) {
|
||||
// 右侧堆叠窗口
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = slave_right_surplus_height * c->stack_innder_per /
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
h = slave_right_surplus_height * c->stack_inner_per /
|
||||
slave_right_surplus_ratio;
|
||||
slave_right_surplus_height =
|
||||
slave_right_surplus_height - h;
|
||||
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;
|
||||
} else {
|
||||
h = (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
h / (m->w.height - ety - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
@@ -770,19 +770,19 @@ void center_tile(Monitor *m) {
|
||||
ety += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
// 左侧堆叠窗口
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = slave_left_surplus_height * c->stack_innder_per /
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
h = slave_left_surplus_height * c->stack_inner_per /
|
||||
slave_left_surplus_ratio;
|
||||
slave_left_surplus_height =
|
||||
slave_left_surplus_height - h;
|
||||
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;
|
||||
} else {
|
||||
h = (m->w.height - oty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per =
|
||||
c->stack_inner_per =
|
||||
h / (m->w.height - oty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
@@ -884,22 +884,22 @@ void tile(Monitor *m) {
|
||||
my += c->geom.height + cur_gappiv * ie;
|
||||
} else {
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = slave_surplus_height * c->stack_innder_per /
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
h = slave_surplus_height * c->stack_inner_per /
|
||||
slave_surplus_ratio;
|
||||
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;
|
||||
} else {
|
||||
h = (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = h / (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
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,
|
||||
(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;
|
||||
} else {
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
h = slave_surplus_height * c->stack_innder_per /
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
h = slave_surplus_height * c->stack_inner_per /
|
||||
slave_surplus_ratio;
|
||||
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;
|
||||
} else {
|
||||
h = (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = h / (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
|
||||
cur_gappiv * ie * (r - 1));
|
||||
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,
|
||||
(struct wlr_box){.x = m->w.x + cur_gappoh,
|
||||
@@ -1047,3 +1047,14 @@ monocle(Monitor *m) {
|
||||
if ((c = focustop(m)))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ static void vertical_grid(Monitor *m);
|
||||
static void vertical_scroller(Monitor *m);
|
||||
static void vertical_deck(Monitor *mon);
|
||||
static void dual_scroller(Monitor *mon);
|
||||
static void tgmix(Monitor *m);
|
||||
|
||||
/* layout(s) */
|
||||
Layout overviewlayout = {"", overview, "overview"};
|
||||
@@ -29,6 +30,7 @@ enum {
|
||||
VERTICAL_DECK,
|
||||
RIGHT_TILE,
|
||||
DUAL_SCROLLER,
|
||||
TGMIX,
|
||||
};
|
||||
|
||||
Layout layouts[] = {
|
||||
@@ -47,4 +49,5 @@ Layout layouts[] = {
|
||||
{"VG", vertical_grid, "vertical_grid", VERTICAL_GRID}, // 垂直格子布局
|
||||
{"VK", vertical_deck, "vertical_deck", VERTICAL_DECK}, // 垂直卡片布局
|
||||
{"DS", dual_scroller, "dual_scroller", DUAL_SCROLLER}, // 双行滚动布局
|
||||
{"TG", tgmix, "tgmix", TGMIX}, // 混合布局
|
||||
};
|
||||
@@ -78,17 +78,17 @@ void vertical_tile(Monitor *m) {
|
||||
mx += c->geom.width + cur_gapih * ie;
|
||||
} else {
|
||||
r = n - i;
|
||||
if (c->stack_innder_per > 0.0f) {
|
||||
w = slave_surplus_width * c->stack_innder_per /
|
||||
if (c->stack_inner_per > 0.0f) {
|
||||
w = slave_surplus_width * c->stack_inner_per /
|
||||
slave_surplus_ratio;
|
||||
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;
|
||||
} else {
|
||||
w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) /
|
||||
r;
|
||||
c->stack_innder_per = w / (m->w.width - tx - cur_gapih -
|
||||
cur_gapih * ie * (r - 1));
|
||||
c->stack_inner_per = w / (m->w.width - tx - cur_gapih -
|
||||
cur_gapih * ie * (r - 1));
|
||||
c->master_mfact_per = mfact;
|
||||
}
|
||||
|
||||
|
||||
78
src/mango.c
78
src/mango.c
@@ -165,7 +165,7 @@ enum {
|
||||
}; /* EWMH atoms */
|
||||
#endif
|
||||
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 { PREV, NEXT };
|
||||
enum { STATE_UNSPECIFIED = 0, STATE_ENABLED, STATE_DISABLED };
|
||||
@@ -364,6 +364,7 @@ struct Client {
|
||||
int isglobal;
|
||||
int isnoborder;
|
||||
int isnoshadow;
|
||||
int isnoradius;
|
||||
int isnoanimation;
|
||||
int isopensilent;
|
||||
int istagsilent;
|
||||
@@ -394,8 +395,8 @@ struct Client {
|
||||
float unfocused_opacity;
|
||||
char oldmonname[128];
|
||||
int noblur;
|
||||
double master_mfact_per, master_inner_per, stack_innder_per;
|
||||
double old_master_mfact_per, old_master_inner_per, old_stack_innder_per;
|
||||
double master_mfact_per, master_inner_per, stack_inner_per;
|
||||
double old_master_mfact_per, old_master_inner_per, old_stack_inner_per;
|
||||
double old_scroller_pproportion;
|
||||
bool ismaster;
|
||||
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_tiling_clients;
|
||||
uint32_t visible_scroll_tiling_clients;
|
||||
bool has_visible_fullscreen_client;
|
||||
struct wlr_scene_optimized_blur *blur;
|
||||
char last_surface_ws_name[256];
|
||||
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_close;
|
||||
struct dvec2 *baked_points_focus;
|
||||
struct dvec2 *baked_points_opafadein;
|
||||
struct dvec2 *baked_points_opafadeout;
|
||||
|
||||
static struct wl_event_source *hide_source;
|
||||
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, isnoborder);
|
||||
APPLY_INT_PROP(c, r, isnoshadow);
|
||||
APPLY_INT_PROP(c, r, isnoradius);
|
||||
APPLY_INT_PROP(c, r, isnoanimation);
|
||||
APPLY_INT_PROP(c, r, isopensilent);
|
||||
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
|
||||
// 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);
|
||||
} else {
|
||||
c->float_geom = c->geom;
|
||||
}
|
||||
|
||||
/*-----------------------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
|
||||
*/
|
||||
/* Notify the client with pointer focus of the axis event. */
|
||||
wlr_seat_pointer_notify_axis(seat, // 滚轮事件发送给客户端也就是窗口
|
||||
event->time_msec, event->orientation,
|
||||
event->delta, event->delta_discrete,
|
||||
event->source, event->relative_direction);
|
||||
wlr_seat_pointer_notify_axis(
|
||||
seat, // 滚轮事件发送给客户端也就是窗口
|
||||
event->time_msec, event->orientation, event->delta * axis_scroll_factor,
|
||||
roundf(event->delta_discrete * axis_scroll_factor), event->source,
|
||||
event->relative_direction);
|
||||
}
|
||||
|
||||
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) {
|
||||
int inhibited = 0, unused_lx, unused_ly;
|
||||
int inhibited = 0;
|
||||
Client *c = NULL;
|
||||
struct wlr_surface *surface = NULL;
|
||||
struct wlr_idle_inhibitor_v1 *inhibitor;
|
||||
|
||||
wl_list_for_each(inhibitor, &idle_inhibit_mgr->inhibitors, link) {
|
||||
struct wlr_surface *surface =
|
||||
wlr_surface_get_root_surface(inhibitor->surface);
|
||||
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;
|
||||
if (exclude != surface &&
|
||||
(inhibit_regardless_of_visibility ||
|
||||
(!tree ||
|
||||
wlr_scene_node_coords(&tree->node, &unused_lx, &unused_ly)))) {
|
||||
if (!tree || (tree->node.enabled && (!c || !c->animation.tagouting))) {
|
||||
inhibited = 1;
|
||||
break;
|
||||
}
|
||||
@@ -3436,13 +3454,13 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym,
|
||||
keycode == k->keysymcode.keycode.keycode3))) &&
|
||||
k->func) {
|
||||
|
||||
isbreak = k->func(&k->arg);
|
||||
|
||||
if (!k->ispassapply)
|
||||
handled = 1;
|
||||
else
|
||||
handled = 0;
|
||||
|
||||
isbreak = k->func(&k->arg);
|
||||
|
||||
if (isbreak)
|
||||
break;
|
||||
}
|
||||
@@ -3708,18 +3726,24 @@ void init_client_properties(Client *c) {
|
||||
c->no_force_center = 0;
|
||||
c->isnoborder = 0;
|
||||
c->isnosizehint = 0;
|
||||
c->isnoradius = 0;
|
||||
c->isnoshadow = 0;
|
||||
c->ignore_maximize = 1;
|
||||
c->ignore_minimize = 1;
|
||||
c->iscustomsize = 0;
|
||||
c->master_mfact_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->allow_csd = 0;
|
||||
c->force_maximize = 0;
|
||||
c->force_tearing = 0;
|
||||
c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
|
||||
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
|
||||
@@ -4023,7 +4047,11 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
||||
.y = grabc->geom.y,
|
||||
.width = (int)round(cursor->x) - grabc->geom.x,
|
||||
.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;
|
||||
} else {
|
||||
resize_tile_client(grabc, true, 0, 0, time);
|
||||
@@ -4319,7 +4347,7 @@ void exchange_two_client(Client *c1, Client *c2) {
|
||||
uint32_t tmp_tags;
|
||||
double master_inner_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 ||
|
||||
(!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_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_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_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 *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);
|
||||
backup_box = c->geom;
|
||||
hit = applyrulesgeom(c);
|
||||
|
||||
Reference in New Issue
Block a user