diff --git a/assets/config.conf b/assets/config.conf index 15b654c1..eb326d16 100644 --- a/assets/config.conf +++ b/assets/config.conf @@ -34,7 +34,7 @@ animation_type_close=slide animation_fade_in=1 animation_fade_out=1 tag_animation_direction=1 -zoom_initial_ratio=0.3 +zoom_initial_ratio=0.4 zoom_end_ratio=0.8 fadein_begin_opacity=0.5 fadeout_begin_opacity=0.8 diff --git a/docs/bindings/keys.md b/docs/bindings/keys.md index 4c318fb3..b3a4ab64 100644 --- a/docs/bindings/keys.md +++ b/docs/bindings/keys.md @@ -195,6 +195,16 @@ bind=NONE,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SINK@ toggle bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle ``` +#### Playback + +Requires: `playerctl` + +```ini +bind=NONE,XF86AudioNext,spawn,playerctl next +bind=NONE,XF86AudioPrev,spawn,playerctl previous +bind=NONE,XF86AudioPlay,spawn,playerctl play-pause +``` + ### Floating Window Movement | Command | Param | Description | @@ -202,4 +212,4 @@ bind=SHIFT,XF86AudioMute,spawn,wpctl set-mute @DEFAULT_SOURCE@ toggle | `smartmovewin` | `left/right/up/down` | Move floating window by snap distance. | | `smartresizewin` | `left/right/up/down` | Resize floating window by snap distance. | | `movewin` | `(x,y)` | Move floating window. | -| `resizewin` | `(width,height)` | Resize window. | \ No newline at end of file +| `resizewin` | `(width,height)` | Resize window. | diff --git a/docs/configuration/input.md b/docs/configuration/input.md index 6d5eefdb..ac30f179 100644 --- a/docs/configuration/input.md +++ b/docs/configuration/input.md @@ -45,6 +45,7 @@ Specific settings for laptop touchpads. Some settings may require a relogin to t | `tap_to_click` | `1` | Tap to trigger a left click. | | `tap_and_drag` | `1` | Tap and hold to drag items. | | `trackpad_natural_scrolling` | `0` | Invert scrolling direction (natural scrolling). | +| `scroll_button` | `274` | The mouse button that use for scrolling(272 to 279). | `scroll_method` | `1` | `1` (Two-finger), `2` (Edge), `4` (Button). | | `click_method` | `1` | `1` (Button areas), `2` (Clickfinger). | | `drag_lock` | `1` | Lock dragging after tapping. | @@ -57,6 +58,16 @@ Specific settings for laptop touchpads. Some settings may require a relogin to t **Detailed descriptions:** +- `scroll_button` values: + - `272` — Left button. + - `273` — Right button. + - `274` — Middle button. + - `275` — Side button. + - `276` — Extra button. + - `277` — Forward button. + - `278` — Back button. + - `279` — Task button. + - `scroll_method` values: - `0` — Never send scroll events (no scrolling). - `1` — Two-finger scrolling: send scroll events when two fingers are logically down on the device. diff --git a/docs/installation.md b/docs/installation.md index d3b9afaa..6f3927a0 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 mangowc +pikman install mangowm ``` --- diff --git a/docs/visuals/animations.md b/docs/visuals/animations.md index b4b88816..76477e05 100644 --- a/docs/visuals/animations.md +++ b/docs/visuals/animations.md @@ -46,7 +46,7 @@ fadeout_begin_opacity=0.5 Adjust the zoom ratios for zoom animations. ```ini -zoom_initial_ratio=0.3 +zoom_initial_ratio=0.4 zoom_end_ratio=0.8 ``` diff --git a/docs/window-management/rules.md b/docs/window-management/rules.md index d37120de..93e81eba 100644 --- a/docs/window-management/rules.md +++ b/docs/window-management/rules.md @@ -27,7 +27,7 @@ windowrule=Parameter:Values,Parameter:Values,appid:Values,title:Values | `isoverlay` | integer | `0` / `1` | Make it always in top layer | | `isopensilent` | integer | `0` / `1` | Open without focus | | `istagsilent` | integer | `0` / `1` | Don't focus if client is not in current view tag | -| `force_maximize` | integer | `0` / `1` (default 1) | The state of client default to maximized | +| `force_fakemaximize` | integer | `0` / `1` (default 1) | The state of client set to fake maximized | | `ignore_maximize` | integer | `0` / `1` (default 1) | Don't handle maximize request from client | | `ignore_minimize` | integer | `0` / `1` (default 1) | Don't handle minimize request from client | | `force_tiled_state` | integer | `0` / `1` | Deceive the window into thinking it is tiling, so it better adheres to assigned dimensions | diff --git a/meson.build b/meson.build index 5d09d536..64394cd9 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('mango', ['c', 'cpp'], - version : '0.12.7', + version : '0.12.8', ) subdir('protocols') diff --git a/mmsg/mmsg.c b/mmsg/mmsg.c index 4e0e1d8c..0191a635 100644 --- a/mmsg/mmsg.c +++ b/mmsg/mmsg.c @@ -569,12 +569,12 @@ int32_t main(int32_t argc, char *argv[]) { mode = WATCH; break; case 'o': - if (mode == SET) + if (mode == GET || mode == WATCH) + oflag = 1; + else if (mode == SET) output_name = EARGF(usage()); else output_name = ARGF(); - if (!output_name) - oflag = 1; break; case 't': tflag = 1; diff --git a/src/client/client.h b/src/client/client.h index 4788e448..965b4106 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -294,9 +294,8 @@ static inline uint32_t client_set_size(Client *c, uint32_t width, uint32_t height) { #ifdef XWAYLAND if (client_is_x11(c)) { - - struct wlr_surface_state *state = - &c->surface.xwayland->surface->current; + struct wlr_xwayland_surface *surface = c->surface.xwayland; + struct wlr_surface_state *state = &surface->surface->current; if ((int32_t)c->geom.width - 2 * (int32_t)c->bw == (int32_t)state->width && @@ -309,6 +308,22 @@ static inline uint32_t client_set_size(Client *c, uint32_t width, return 0; } + xcb_size_hints_t *size_hints = surface->size_hints; + int32_t width = c->geom.width - 2 * c->bw; + int32_t height = c->geom.height - 2 * c->bw; + + if (c->mon && c->mon->isoverview && size_hints && + c->geom.width - 2 * (int32_t)c->bw < size_hints->min_width && + c->geom.height - 2 * (int32_t)c->bw < size_hints->min_height) + return 0; + + if (size_hints && + c->geom.width - 2 * (int32_t)c->bw < size_hints->min_width) + width = size_hints->min_width; + if (size_hints && + c->geom.height - 2 * (int32_t)c->bw < size_hints->min_height) + height = size_hints->min_height; + wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw, c->geom.y + c->bw, width, height); return 1; @@ -350,7 +365,7 @@ static inline void client_set_maximized(Client *c, bool maximized) { static inline void client_set_tiled(Client *c, uint32_t edges) { struct wlr_xdg_toplevel *toplevel; #ifdef XWAYLAND - if (client_is_x11(c) && c->force_maximize) { + if (client_is_x11(c) && c->force_fakemaximize) { wlr_xwayland_surface_set_maximized(c->surface.xwayland, edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE); @@ -365,7 +380,7 @@ static inline void client_set_tiled(Client *c, uint32_t edges) { wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges); } - if (c->force_maximize) { + if (c->force_fakemaximize) { wlr_xdg_toplevel_set_maximized(toplevel, edges != WLR_EDGE_NONE); } } diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 62c8fc87..71bcc71a 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -90,7 +90,7 @@ typedef struct { int32_t no_force_center; int32_t isterm; int32_t allow_csd; - int32_t force_maximize; + int32_t force_fakemaximize; int32_t force_tiled_state; int32_t force_tearing; int32_t noswallow; @@ -2064,7 +2064,7 @@ bool parse_option(Config *config, char *key, char *value) { rule->indleinhibit_when_focus = -1; rule->isterm = -1; rule->allow_csd = -1; - rule->force_maximize = -1; + rule->force_fakemaximize = -1; rule->force_tiled_state = -1; rule->force_tearing = -1; rule->noswallow = -1; @@ -2178,8 +2178,8 @@ bool parse_option(Config *config, char *key, char *value) { rule->isterm = atoi(val); } else if (strcmp(key, "allow_csd") == 0) { rule->allow_csd = atoi(val); - } else if (strcmp(key, "force_maximize") == 0) { - rule->force_maximize = atoi(val); + } else if (strcmp(key, "force_fakemaximize") == 0) { + rule->force_fakemaximize = atoi(val); } else if (strcmp(key, "force_tiled_state") == 0) { rule->force_tiled_state = atoi(val); } else if (strcmp(key, "force_tearing") == 0) { @@ -3224,7 +3224,7 @@ void override_config(void) { config.accel_profile = CLAMP_INT(config.accel_profile, 0, 2); config.accel_speed = CLAMP_FLOAT(config.accel_speed, -1.0f, 1.0f); config.scroll_method = CLAMP_INT(config.scroll_method, 0, 4); - config.scroll_button = CLAMP_INT(config.scroll_button, 272, 276); + config.scroll_button = CLAMP_INT(config.scroll_button, 272, 279); config.click_method = CLAMP_INT(config.click_method, 0, 2); config.send_events_mode = CLAMP_INT(config.send_events_mode, 0, 2); config.button_map = CLAMP_INT(config.button_map, 0, 1); @@ -3274,7 +3274,7 @@ void set_value_default() { config.animation_fade_in = 1; config.animation_fade_out = 1; config.tag_animation_direction = HORIZONTAL; - config.zoom_initial_ratio = 0.3f; + config.zoom_initial_ratio = 0.4f; config.zoom_end_ratio = 0.8f; config.fadein_begin_opacity = 0.5f; config.fadeout_begin_opacity = 0.5f; diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 68309356..ec06ce5a 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -376,7 +376,11 @@ int32_t moveresize(const Arg *arg) { /* Float the window and tell motionnotify to grab it */ if (grabc->isfloating == 0 && arg->ui == CurMove) { grabc->drag_to_tile = true; + exit_scroller_stack(grabc); setfloating(grabc, 1); + grabc->old_stack_inner_per = 0.0f; + grabc->old_master_inner_per = 0.0f; + set_size_per(grabc->mon, grabc); } switch (cursor_mode = arg->ui) { @@ -548,7 +552,7 @@ int32_t restore_minimized(const Arg *arg) { if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && selmon->sel->is_scratchpad_show) { - selmon->sel->isminimized = 0; + client_pending_minimized_state(selmon->sel, 0); selmon->sel->is_scratchpad_show = 0; selmon->sel->is_in_scratchpad = 0; selmon->sel->isnamedscratchpad = 0; diff --git a/src/mango.c b/src/mango.c index b52401f7..62bff0da 100644 --- a/src/mango.c +++ b/src/mango.c @@ -394,7 +394,7 @@ struct Client { struct dwl_opacity_animation opacity_animation; int32_t isterm, noswallow; int32_t allow_csd; - int32_t force_maximize; + int32_t force_fakemaximize; int32_t force_tiled_state; pid_t pid; Client *swallowing, *swallowedby; @@ -810,6 +810,10 @@ 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,11 +1071,33 @@ 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) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); + client_pending_maximized_state(c, 0); c->bw = c->isnoborder ? 0 : config.borderpx; } @@ -1110,9 +1136,6 @@ 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; @@ -1124,6 +1147,7 @@ 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) @@ -1142,11 +1166,9 @@ void swallow(Client *c, Client *w) { if (!c->foreign_toplevel && c->mon) add_foreign_toplevel(c); - 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); - } + client_pending_fullscreen_state(c, w->isfullscreen); + client_pending_maximized_state(c, w->ismaximizescreen); + client_pending_minimized_state(c, w->isminimized); } bool switch_scratchpad_client_state(Client *c) { @@ -1329,7 +1351,7 @@ void toggle_hotarea(int32_t x_root, int32_t y_root) { static void apply_rule_properties(Client *c, const ConfigWinRule *r) { APPLY_INT_PROP(c, r, isterm); APPLY_INT_PROP(c, r, allow_csd); - APPLY_INT_PROP(c, r, force_maximize); + APPLY_INT_PROP(c, r, force_fakemaximize); APPLY_INT_PROP(c, r, force_tiled_state); APPLY_INT_PROP(c, r, force_tearing); APPLY_INT_PROP(c, r, noswallow); @@ -4092,7 +4114,7 @@ void init_client_properties(Client *c) { c->old_master_mfact_per = 0.0f; c->isterm = 0; c->allow_csd = 0; - c->force_maximize = 0; + c->force_fakemaximize = 0; c->force_tiled_state = 1; c->force_tearing = 0; c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; @@ -4250,7 +4272,7 @@ void maximizenotify(struct wl_listener *listener, void *data) { void unminimize(Client *c) { if (c && c->is_in_scratchpad && c->is_scratchpad_show) { - c->isminimized = 0; + client_pending_minimized_state(c, 0); c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; @@ -4278,13 +4300,12 @@ void set_minimized(Client *c) { c->oldtags = c->mon->tagset[c->mon->seltags]; c->mini_restore_tag = c->tags; c->tags = 0; - c->isminimized = 1; + client_pending_minimized_state(c, 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); // 插入尾部 } @@ -5061,11 +5082,11 @@ setfloating(Client *c, int32_t floating) { if (floating == 1 && c != grabc) { if (c->isfullscreen) { - c->isfullscreen = 0; + client_pending_fullscreen_state(c, 0); client_set_fullscreen(c, 0); } - c->ismaximizescreen = 0; + client_pending_maximized_state(c, 0); exit_scroller_stack(c); // 重新计算居中的坐标 @@ -5131,7 +5152,7 @@ setfloating(Client *c, int32_t floating) { save_old_size_per(c->mon); } - if (!c->force_maximize) + if (!c->force_fakemaximize) client_set_maximized(c, false); if (!c->isfloating || c->force_tiled_state) { @@ -5190,12 +5211,12 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { return; int32_t old_maximizescreen_state = c->ismaximizescreen; - c->ismaximizescreen = maximizescreen; + client_pending_maximized_state(c, maximizescreen); if (maximizescreen) { if (c->isfullscreen) { - c->isfullscreen = 0; + client_pending_fullscreen_state(c, 0); client_set_fullscreen(c, 0); } @@ -5208,10 +5229,8 @@ 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); } @@ -5226,9 +5245,9 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) { save_old_size_per(c->mon); } - if (!c->force_maximize && !c->ismaximizescreen) { + if (!c->force_fakemaximize && !c->ismaximizescreen) { client_set_maximized(c, false); - } else if (!c->force_maximize && c->ismaximizescreen) { + } else if (!c->force_fakemaximize && c->ismaximizescreen) { client_set_maximized(c, true); } @@ -5259,22 +5278,25 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自 c->isfullscreen = fullscreen; client_set_fullscreen(c, fullscreen); + client_pending_fullscreen_state(c, fullscreen); if (fullscreen) { - c->ismaximizescreen = 0; - exit_scroller_stack(c); + if (c->ismaximizescreen && !c->force_fakemaximize) { + client_set_maximized(c, false); + } + client_pending_maximized_state(c, 0); + + exit_scroller_stack(c); c->isfakefullscreen = 0; c->bw = 0; 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); } @@ -5466,8 +5488,7 @@ void show_hide_client(Client *c) { c->tags = c->oldtags; arrange(c->mon, false, false); } - c->isminimized = 0; - wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); + client_pending_minimized_state(c, 0); focusclient(c, 1); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } @@ -5899,8 +5920,8 @@ void overview_backup(Client *c) { c->isfloating = 0; } if (c->isfullscreen || c->ismaximizescreen) { - c->isfullscreen = 0; // 清除窗口全屏标志 - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); // 清除窗口全屏标志 + client_pending_maximized_state(c, 0); } c->bw = c->isnoborder ? 0 : config.borderpx; @@ -5930,8 +5951,8 @@ void overview_restore(Client *c, const Arg *arg) { } else if (want_restore_fullscreen(c) && c->isfullscreen) { setfullscreen(c, 1); } else { - c->isfullscreen = 0; - c->ismaximizescreen = 0; + client_pending_fullscreen_state(c, 0); + client_pending_maximized_state(c, 0); setfullscreen(c, false); } } else { @@ -6504,13 +6525,11 @@ void activatex11(struct wl_listener *listener, void *data) { return; if (c->isminimized) { - c->isminimized = 0; + client_pending_minimized_state(c, 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;