diff --git a/docs/installation.md b/docs/installation.md index 6f3927a0..d3b9afaa 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -185,7 +185,7 @@ mangowm is available in the **PikaOS package repository**. You can install it using the `pikman` package manager: ```bash -pikman install mangowm +pikman install mangowc ``` --- diff --git a/mangowm.scm b/mangowm.scm index 44031ed0..7d94166d 100644 --- a/mangowm.scm +++ b/mangowm.scm @@ -15,7 +15,7 @@ #:use-module (gnu packages ninja) #:use-module (gnu packages pkg-config) #:use-module (guix build-system meson) - #:use-module ((guix licenses) #:prefix license:)) + #:use-module (guix licenses)) (define-public mangowm-git @@ -36,13 +36,10 @@ (add-before 'configure 'patch-meson (lambda _ (substitute* "meson.build" - ;; MangoWM ignores sysconfdir handling for NixOS. - ;; We also need to skip that sysconfdir edits. - (("is_nixos = false") - "is_nixos = true") - ;; Unhardcode path. Fixes loading default config. (("'-DSYSCONFDIR=\\\"@0@\\\"'.format\\('/etc'\\)") - "'-DSYSCONFDIR=\"@0@\"'.format(sysconfdir)"))))))) + "'-DSYSCONFDIR=\"@0@\"'.format(sysconfdir)") + (("sysconfdir = sysconfdir.substring\\(prefix.length\\(\\)\\)") + ""))))))) (inputs (list wayland libinput libdrm @@ -55,17 +52,14 @@ pcre2 libxcb xcb-util-wm - wlroots-0.19 + wlroots scenefx)) (native-inputs (list pkg-config wayland-protocols)) - (home-page "https://github.com/mangowm/mango") + (home-page "https://github.com/DreamMaoMao/mangowm") (synopsis "Wayland compositor based on wlroots and scenefx") - (description - "MangoWM is a modern, lightweight, high-performance Wayland compositor -built on dwl — crafted for speed, flexibility, and a customizable desktop experience.") - (license (list license:gpl3 ;mangowm itself, dwl - license:expat ;dwm, sway, wlroots - license:cc0)))) ;tinywl + (description "A Wayland compositor based on wlroots and scenefx, +inspired by dwl but aiming to be more feature-rich.") + (license gpl3))) (define-deprecated-package mangowc mangowm-git) diff --git a/nix/hm-modules.nix b/nix/hm-modules.nix index f00d9c68..85d57908 100644 --- a/nix/hm-modules.nix +++ b/nix/hm-modules.nix @@ -1,22 +1,18 @@ -self: -{ +self: { lib, config, pkgs, ... -}: -let +}: let cfg = config.wayland.windowManager.mango; - selflib = import ./lib.nix lib; variables = lib.concatStringsSep " " cfg.systemd.variables; extraCommands = lib.concatStringsSep " && " cfg.systemd.extraCommands; - systemdActivation = "${pkgs.dbus}/bin/dbus-update-activation-environment --systemd ${variables}; ${extraCommands}"; + systemdActivation = ''${pkgs.dbus}/bin/dbus-update-activation-environment --systemd ${variables}; ${extraCommands}''; autostart_sh = pkgs.writeShellScript "autostart.sh" '' ${lib.optionalString cfg.systemd.enable systemdActivation} ${cfg.autostart_sh} ''; -in -{ +in { options = { wayland.windowManager.mango = with lib; { enable = mkOption { @@ -58,7 +54,7 @@ in "XCURSOR_THEME" "XCURSOR_SIZE" ]; - example = [ "--all" ]; + example = ["--all"]; description = '' Environment variables imported into the systemd and D-Bus user environment. ''; @@ -79,195 +75,50 @@ in ''; }; settings = mkOption { - type = - with lib.types; - let - valueType = - nullOr (oneOf [ - bool - int - float - str - path - (attrsOf valueType) - (listOf valueType) - ]) - // { - description = "Mango configuration value"; - }; - in - valueType; - default = { }; - description = '' - Mango configuration written in Nix. Entries with the same key - should be written as lists. Variables and colors names should be - quoted. See for more examples. - - ::: {.note} - This option uses a structured format that is converted to Mango's - configuration syntax. Nested attributes are flattened with underscore separators. - For example: `animation.duration_open = 400` becomes `animation_duration_open = 400` - - Keymodes (submaps) are supported via the special `keymode` attribute. Each keymode - is a nested attribute set under `keymode` that contains its own bindings. - ::: - ''; - example = lib.literalExpression '' - { - # Window effects - blur = 1; - blur_optimized = 1; - blur_params = { - radius = 5; - num_passes = 2; - }; - border_radius = 6; - focused_opacity = 1.0; - - # Animations - use underscores for multi-part keys - animations = 1; - animation_type_open = "slide"; - animation_type_close = "slide"; - animation_duration_open = 400; - animation_duration_close = 800; - - # Or use nested attrs (will be flattened with underscores) - animation_curve = { - open = "0.46,1.0,0.29,1"; - close = "0.08,0.92,0,1"; - }; - - # Use lists for duplicate keys like bind and tagrule - bind = [ - "SUPER,r,reload_config" - "Alt,space,spawn,rofi -show drun" - "Alt,Return,spawn,foot" - "ALT,R,setkeymode,resize" # Enter resize mode - ]; - - tagrule = [ - "id:1,layout_name:tile" - "id:2,layout_name:scroller" - ]; - - # Keymodes (submaps) for modal keybindings - keymode = { - resize = { - bind = [ - "NONE,Left,resizewin,-10,0" - "NONE,Escape,setkeymode,default" - ]; - }; - }; - } - ''; - }; - extraConfig = mkOption { + description = "mango config content"; type = types.lines; default = ""; - description = '' - Extra configuration lines to add to `~/.config/mango/config.conf`. - This is useful for advanced configurations that don't fit the structured - settings format, or for options that aren't yet supported by the module. - ''; example = '' - # Advanced config that doesn't fit structured format - special_option = 1 + # menu and terminal + bind=Alt,space,spawn,rofi -show drun + bind=Alt,Return,spawn,foot ''; }; - topPrefixes = mkOption { - type = with lib.types; listOf str; - default = [ ]; - description = '' - List of prefixes for attributes that should appear at the top of the config file. - Attributes starting with these prefixes will be sorted to the beginning. - ''; - example = [ "source" ]; - }; - bottomPrefixes = mkOption { - type = with lib.types; listOf str; - default = [ ]; - description = '' - List of prefixes for attributes that should appear at the bottom of the config file. - Attributes starting with these prefixes will be sorted to the end. - ''; - example = [ "source" ]; - }; autostart_sh = mkOption { - description = '' - Shell script to run on mango startup. No shebang needed. - - When this option is set, the script will be written to - `~/.config/mango/autostart.sh` and an `exec-once` line - will be automatically added to the config to execute it. - ''; + description = "WARRNING: This is a shell script, but no need to add shebang"; type = types.lines; default = ""; example = '' waybar & - dunst & ''; }; }; }; - config = lib.mkIf cfg.enable ( - let - finalConfigText = - # Support old string-based config during transition period - ( - if builtins.isString cfg.settings then - cfg.settings - else - lib.optionalString (cfg.settings != { }) ( - selflib.toMango { - topCommandsPrefixes = cfg.topPrefixes; - bottomCommandsPrefixes = cfg.bottomPrefixes; - } cfg.settings - ) - ) - + lib.optionalString (cfg.extraConfig != "") cfg.extraConfig - + lib.optionalString (cfg.autostart_sh != "") "\nexec-once=~/.config/mango/autostart.sh\n"; - - validatedConfig = pkgs.runCommand "mango-config.conf" { } '' - cp ${pkgs.writeText "mango-config.conf" finalConfigText} "$out" - ${cfg.package}/bin/mango -c "$out" -p || exit 1 - ''; - in - { - # Backwards compatibility warning for old string-based config - warnings = lib.optional (builtins.isString cfg.settings) '' - wayland.windowManager.mango.settings: Using a string for settings is deprecated. - Please migrate to the new structured attribute set format. - See the module documentation for examples, or use the 'extraConfig' option for raw config strings. - The old string format will be removed in a future release. - ''; - - home.packages = [ cfg.package ]; - xdg.configFile = { - "mango/config.conf" = - lib.mkIf (cfg.settings != { } || cfg.extraConfig != "" || cfg.autostart_sh != "") - { - source = validatedConfig; - }; - "mango/autostart.sh" = lib.mkIf (cfg.autostart_sh != "") { - source = autostart_sh; - executable = true; - }; + config = lib.mkIf cfg.enable { + home.packages = [cfg.package]; + xdg.configFile = { + "mango/config.conf" = lib.mkIf (cfg.settings != "") { + text = cfg.settings; }; - systemd.user.targets.mango-session = lib.mkIf cfg.systemd.enable { - Unit = { - Description = "mango compositor session"; - Documentation = [ "man:systemd.special(7)" ]; - BindsTo = [ "graphical-session.target" ]; - Wants = [ + "mango/autostart.sh" = lib.mkIf (cfg.autostart_sh != "") { + source = autostart_sh; + executable = true; + }; + }; + systemd.user.targets.mango-session = lib.mkIf cfg.systemd.enable { + Unit = { + Description = "mango compositor session"; + Documentation = ["man:systemd.special(7)"]; + BindsTo = ["graphical-session.target"]; + Wants = + [ "graphical-session-pre.target" ] ++ lib.optional cfg.systemd.xdgAutostart "xdg-desktop-autostart.target"; - After = [ "graphical-session-pre.target" ]; - Before = lib.optional cfg.systemd.xdgAutostart "xdg-desktop-autostart.target"; - }; + After = ["graphical-session-pre.target"]; + Before = lib.optional cfg.systemd.xdgAutostart "xdg-desktop-autostart.target"; }; - } - ); + }; + }; } diff --git a/nix/lib.nix b/nix/lib.nix deleted file mode 100644 index 9dfd2ff6..00000000 --- a/nix/lib.nix +++ /dev/null @@ -1,312 +0,0 @@ -lib: -let - inherit (lib) - attrNames - filterAttrs - foldl - generators - partition - removeAttrs - ; - - inherit (lib.strings) - concatMapStrings - hasPrefix - ; - - /** - Convert a structured Nix attribute set into Mango's configuration format. - - This function takes a nested attribute set and converts it into Mango-compatible - configuration syntax, supporting top, bottom, and regular command sections. - - Commands are flattened using the `flattenAttrs` function, and attributes are formatted as - `key = value` pairs. Lists are expanded as duplicate keys to match Mango's expected format. - - Configuration: - - * `topCommandsPrefixes` - A list of prefixes to define **top** commands (default: `[]`). - * `bottomCommandsPrefixes` - A list of prefixes to define **bottom** commands (default: `[]`). - - Attention: - - - The function ensures top commands appear **first** and bottom commands **last**. - - The generated configuration is a **single string**, suitable for writing to a config file. - - Lists are converted into multiple entries, ensuring compatibility with Mango. - - # Inputs - - Structured function argument: - - : topCommandsPrefixes (optional, default: `[]`) - : A list of prefixes that define **top** commands. Any key starting with one of these - prefixes will be placed at the beginning of the configuration. - : bottomCommandsPrefixes (optional, default: `[]`) - : A list of prefixes that define **bottom** commands. Any key starting with one of these - prefixes will be placed at the end of the configuration. - - Value: - - : The attribute set to be converted to Hyprland configuration format. - - # Type - - ``` - toMango :: AttrSet -> AttrSet -> String - ``` - - # Examples - :::{.example} - - ## Basic mangowc configuration - - ```nix - let - config = { - blur = 1; - blur_params_radius = 5; - border_radius = 6; - animations = 1; - animation_duration_open = 400; - }; - in lib.toMango {} config - ``` - - **Output:** - ``` - animations = 1 - animation_duration_open = 400 - blur = 1 - blur_params_radius = 5 - border_radius = 6 - ``` - - ## Using nested attributes - - ```nix - let - config = { - blur = 1; - blur_params = { - radius = 5; - num_passes = 2; - noise = 0.02; - }; - animation_curve = { - open = "0.46,1.0,0.29,1"; - close = "0.08,0.92,0,1"; - }; - }; - in lib.toMango {} config - ``` - - **Output:** - ``` - animation_curve_close = 0.08,0.92,0,1 - animation_curve_open = 0.46,1.0,0.29,1 - blur = 1 - blur_params_noise = 0.02 - blur_params_num_passes = 2 - blur_params_radius = 5 - ``` - - ## Using lists for duplicate keys - - ```nix - let - config = { - bind = [ - "SUPER,r,reload_config" - "Alt,space,spawn,rofi -show drun" - "Alt,Return,spawn,foot" - ]; - tagrule = [ - "id:1,layout_name:tile" - "id:2,layout_name:scroller" - ]; - }; - in lib.toMango {} config - ``` - - **Output:** - ``` - bind = SUPER,r,reload_config - bind = Alt,space,spawn,rofi -show drun - bind = Alt,Return,spawn,foot - tagrule = id:1,layout_name:tile - tagrule = id:2,layout_name:scroller - ``` - - ## Using keymodes (submaps) - - ```nix - let - config = { - bind = [ - "SUPER,Q,killclient" - "ALT,R,setkeymode,resize" - ]; - keymode = { - resize = { - bind = [ - "NONE,Left,resizewin,-10,0" - "NONE,Right,resizewin,10,0" - "NONE,Escape,setkeymode,default" - ]; - }; - }; - }; - in lib.toMango {} config - ``` - - **Output:** - ``` - bind = SUPER,Q,killclient - bind = ALT,R,setkeymode,resize - - keymode = resize - bind = NONE,Left,resizewin,-10,0 - bind = NONE,Right,resizewin,10,0 - bind = NONE,Escape,setkeymode,default - ``` - - ::: - */ - toMango = - { - topCommandsPrefixes ? [ ], - bottomCommandsPrefixes ? [ ], - }: - attrs: - let - toMango' = - attrs: - let - # Specially configured `toKeyValue` generator with support for duplicate keys - # and a legible key-value separator. - mkCommands = generators.toKeyValue { - mkKeyValue = generators.mkKeyValueDefault { } " = "; - listsAsDuplicateKeys = true; - indent = ""; # No indent, since we don't have nesting - }; - - # Extract keymode definitions if they exist - keymodes = attrs.keymode or { }; - attrsWithoutKeymodes = removeAttrs attrs [ "keymode" ]; - - # Generate keymode blocks - # Format: keymode=name\nbind=...\nbind=...\n - mkKeymodeBlock = - name: modeAttrs: - let - modeCommands = flattenAttrs (p: k: "${p}_${k}") modeAttrs; - in - "keymode = ${name}\n${mkCommands modeCommands}"; - - keymodeBlocks = - if keymodes == { } then - "" - else - "\n" + concatMapStrings (name: mkKeymodeBlock name keymodes.${name} + "\n") (attrNames keymodes); - - # Flatten the attrset, combining keys in a "path" like `"a_b_c" = "x"`. - # Uses `flattenAttrs` with an underscore separator. - commands = flattenAttrs (p: k: "${p}_${k}") attrsWithoutKeymodes; - - # General filtering function to check if a key starts with any prefix in a given list. - filterCommands = list: n: foldl (acc: prefix: acc || hasPrefix prefix n) false list; - - # Partition keys into top commands and the rest - result = partition (filterCommands topCommandsPrefixes) (attrNames commands); - topCommands = filterAttrs (n: _: builtins.elem n result.right) commands; - remainingCommands = removeAttrs commands result.right; - - # Partition remaining commands into bottom commands and regular commands - result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong; - bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands; - regularCommands = removeAttrs remainingCommands result2.right; - in - # Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands. - # Keymodes are appended at the end. - concatMapStrings mkCommands [ - topCommands - regularCommands - bottomCommands - ] - + keymodeBlocks; - in - toMango' attrs; - - /** - Flatten a nested attribute set into a flat attribute set, using a custom key separator function. - - This function recursively traverses a nested attribute set and produces a flat attribute set - where keys are joined using a user-defined function (`pred`). It allows transforming deeply - nested structures into a single-level attribute set while preserving key-value relationships. - - Configuration: - - * `pred` - A function `(string -> string -> string)` defining how keys should be concatenated. - - # Inputs - - Structured function argument: - - : pred (required) - : A function that determines how parent and child keys should be combined into a single key. - It takes a `prefix` (parent key) and `key` (current key) and returns the joined key. - - Value: - - : The nested attribute set to be flattened. - - # Type - - ``` - flattenAttrs :: (String -> String -> String) -> AttrSet -> AttrSet - ``` - - # Examples - :::{.example} - - ```nix - let - nested = { - a = "3"; - b = { c = "4"; d = "5"; }; - }; - - separator = (prefix: key: "${prefix}.${key}"); # Use dot notation - in lib.flattenAttrs separator nested - ``` - - **Output:** - ```nix - { - "a" = "3"; - "b.c" = "4"; - "b.d" = "5"; - } - ``` - - ::: - */ - flattenAttrs = - pred: attrs: - let - flattenAttrs' = - prefix: attrs: - builtins.foldl' ( - acc: key: - let - value = attrs.${key}; - newKey = if prefix == "" then key else pred prefix key; - in - acc // (if builtins.isAttrs value then flattenAttrs' newKey value else { "${newKey}" = value; }) - ) { } (builtins.attrNames attrs); - in - flattenAttrs' "" attrs; -in -{ - inherit flattenAttrs toMango; -} diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index f5992e29..07eafde5 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -552,7 +552,7 @@ int32_t restore_minimized(const Arg *arg) { if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && selmon->sel->is_scratchpad_show) { - client_pending_minimized_state(selmon->sel, 0); + selmon->sel->isminimized = 0; selmon->sel->is_scratchpad_show = 0; selmon->sel->is_in_scratchpad = 0; selmon->sel->isnamedscratchpad = 0; @@ -863,6 +863,7 @@ int32_t spawn_shell(const Arg *arg) { } int32_t spawn(const Arg *arg) { + if (!arg->v) return 0; @@ -875,21 +876,28 @@ int32_t spawn(const Arg *arg) { dup2(STDERR_FILENO, STDOUT_FILENO); setsid(); - // 2. 对整个参数字符串进行单词展开 - wordexp_t p; - if (wordexp(arg->v, &p, 0) != 0) { - wlr_log(WLR_DEBUG, "mango: wordexp failed for '%s'\n", arg->v); - _exit(EXIT_FAILURE); + // 2. 解析参数 + char *argv[64]; + int32_t argc = 0; + char *token = strtok((char *)arg->v, " "); + while (token != NULL && argc < 63) { + wordexp_t p; + if (wordexp(token, &p, 0) == 0) { + argv[argc++] = p.we_wordv[0]; + } else { + argv[argc++] = token; + } + token = strtok(NULL, " "); } + argv[argc] = NULL; - // 3. 执行命令(p.we_wordv 已经是 argv 数组) - execvp(p.we_wordv[0], p.we_wordv); + // 3. 执行命令 + execvp(argv[0], argv); - // 4. execvp 失败时:打印错误,释放 wordexp 资源,然后退出 - wlr_log(WLR_DEBUG, "mango: execvp '%s' failed: %s\n", p.we_wordv[0], + // 4. execvp 失败时:打印错误并直接退出(避免 coredump) + wlr_log(WLR_DEBUG, "mango: execvp '%s' failed: %s\n", argv[0], strerror(errno)); - wordfree(&p); // 释放 wordexp 分配的内存 - _exit(EXIT_FAILURE); + _exit(EXIT_FAILURE); // 使用 _exit 避免缓冲区刷新等操作 } return 0; } diff --git a/src/mango.c b/src/mango.c index 8fdff709..fad86b20 100644 --- a/src/mango.c +++ b/src/mango.c @@ -806,10 +806,6 @@ static int32_t keep_idle_inhibit(void *data); static void check_keep_idle_inhibit(Client *c); static void pre_caculate_before_arrange(Monitor *m, bool want_animation, bool from_view, bool only_caculate); -static void client_pending_fullscreen_state(Client *c, int32_t isfullscreen); -static void client_pending_maximized_state(Client *c, int32_t ismaximized); -static void client_pending_minimized_state(Client *c, int32_t isminimized); - #include "data/static_keymap.h" #include "dispatch/bind_declare.h" #include "layout/layout.h" @@ -1067,33 +1063,11 @@ void clear_fullscreen_flag(Client *c) { } } -void client_pending_fullscreen_state(Client *c, int32_t isfullscreen) { - c->isfullscreen = isfullscreen; - - if (c->foreign_toplevel && !c->iskilling) - wlr_foreign_toplevel_handle_v1_set_fullscreen(c->foreign_toplevel, - isfullscreen); -} - -void client_pending_maximized_state(Client *c, int32_t ismaximized) { - c->ismaximizescreen = ismaximized; - if (c->foreign_toplevel && !c->iskilling) - wlr_foreign_toplevel_handle_v1_set_maximized(c->foreign_toplevel, - ismaximized); -} - -void client_pending_minimized_state(Client *c, int32_t isminimized) { - c->isminimized = isminimized; - if (c->foreign_toplevel && !c->iskilling) - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, - isminimized); -} - void show_scratchpad(Client *c) { c->is_scratchpad_show = 1; if (c->isfullscreen || c->ismaximizescreen) { - client_pending_fullscreen_state(c, 0); - client_pending_maximized_state(c, 0); + c->isfullscreen = 0; // 清除窗口全屏标志 + c->ismaximizescreen = 0; c->bw = c->isnoborder ? 0 : config.borderpx; } @@ -1132,6 +1106,9 @@ void swallow(Client *c, Client *w) { c->bw = w->bw; c->isfloating = w->isfloating; c->isurgent = w->isurgent; + c->isfullscreen = w->isfullscreen; + c->ismaximizescreen = w->ismaximizescreen; + c->isminimized = w->isminimized; c->is_in_scratchpad = w->is_in_scratchpad; c->is_scratchpad_show = w->is_scratchpad_show; c->tags = w->tags; @@ -1143,7 +1120,6 @@ void swallow(Client *c, Client *w) { c->scroller_proportion = w->scroller_proportion; c->next_in_stack = w->next_in_stack; c->prev_in_stack = w->prev_in_stack; - if (w->next_in_stack) w->next_in_stack->prev_in_stack = c; if (w->prev_in_stack) @@ -1162,9 +1138,11 @@ void swallow(Client *c, Client *w) { if (!c->foreign_toplevel && c->mon) add_foreign_toplevel(c); - client_pending_fullscreen_state(c, w->isfullscreen); - client_pending_maximized_state(c, w->ismaximizescreen); - client_pending_minimized_state(c, w->isminimized); + if (c->isminimized && c->foreign_toplevel) { + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, + false); + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); + } } bool switch_scratchpad_client_state(Client *c) { @@ -4253,7 +4231,7 @@ void maximizenotify(struct wl_listener *listener, void *data) { void unminimize(Client *c) { if (c && c->is_in_scratchpad && c->is_scratchpad_show) { - client_pending_minimized_state(c, 0); + c->isminimized = 0; c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; @@ -4281,12 +4259,13 @@ void set_minimized(Client *c) { c->oldtags = c->mon->tagset[c->mon->seltags]; c->mini_restore_tag = c->tags; c->tags = 0; - client_pending_minimized_state(c, 1); + c->isminimized = 1; c->is_in_scratchpad = 1; c->is_scratchpad_show = 0; focusclient(focustop(selmon), 1); arrange(c->mon, false, false); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); wl_list_remove(&c->link); // 从原来位置移除 wl_list_insert(clients.prev, &c->link); // 插入尾部 } @@ -5063,11 +5042,11 @@ setfloating(Client *c, int32_t floating) { if (floating == 1 && c != grabc) { if (c->isfullscreen) { - client_pending_fullscreen_state(c, 0); + c->isfullscreen = 0; client_set_fullscreen(c, 0); } - client_pending_maximized_state(c, 0); + c->ismaximizescreen = 0; exit_scroller_stack(c); // 重新计算居中的坐标 @@ -5192,12 +5171,12 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { return; int32_t old_maximizescreen_state = c->ismaximizescreen; - client_pending_maximized_state(c, maximizescreen); + c->ismaximizescreen = maximizescreen; if (maximizescreen) { if (c->isfullscreen) { - client_pending_fullscreen_state(c, 0); + c->isfullscreen = 0; client_set_fullscreen(c, 0); } @@ -5210,8 +5189,10 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { wlr_scene_node_raise_to_top(&c->scene->node); if (!is_scroller_layout(c->mon) || c->isfloating) resize(c, maximizescreen_box, 0); + c->ismaximizescreen = 1; } else { c->bw = c->isnoborder ? 0 : config.borderpx; + c->ismaximizescreen = 0; if (c->isfloating) setfloating(c, 1); } @@ -5259,7 +5240,6 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 c->isfullscreen = fullscreen; client_set_fullscreen(c, fullscreen); - client_pending_fullscreen_state(c, fullscreen); if (fullscreen) { @@ -5267,7 +5247,7 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 client_set_maximized(c, false); } - client_pending_maximized_state(c, 0); + c->ismaximizescreen = 0; exit_scroller_stack(c); c->isfakefullscreen = 0; @@ -5276,8 +5256,10 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 if (!is_scroller_layout(c->mon) || c->isfloating) resize(c, c->mon->m, 1); + c->isfullscreen = 1; } else { c->bw = c->isnoborder ? 0 : config.borderpx; + c->isfullscreen = 0; if (c->isfloating) setfloating(c, 1); } @@ -5469,7 +5451,8 @@ void show_hide_client(Client *c) { c->tags = c->oldtags; arrange(c->mon, false, false); } - client_pending_minimized_state(c, 0); + c->isminimized = 0; + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); focusclient(c, 1); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } @@ -5893,8 +5876,8 @@ void overview_backup(Client *c) { c->isfloating = 0; } if (c->isfullscreen || c->ismaximizescreen) { - client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志 - client_pending_maximized_state(c, 0); + c->isfullscreen = 0; // 清除窗口全屏标志 + c->ismaximizescreen = 0; } c->bw = c->isnoborder ? 0 : config.borderpx; @@ -5924,8 +5907,8 @@ void overview_restore(Client *c, const Arg *arg) { } else if (want_restore_fullscreen(c) && c->isfullscreen) { setfullscreen(c, 1); } else { - client_pending_fullscreen_state(c, 0); - client_pending_maximized_state(c, 0); + c->isfullscreen = 0; + c->ismaximizescreen = 0; setfullscreen(c, false); } } else { @@ -6498,11 +6481,13 @@ void activatex11(struct wl_listener *listener, void *data) { return; if (c->isminimized) { - client_pending_minimized_state(c, 0); + c->isminimized = 0; c->tags = c->mini_restore_tag; c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; + wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, + false); setborder_color(c); if (VISIBLEON(c, c->mon)) { need_arrange = true;