mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-16 14:33:36 -04:00
feat: add overview jump mode
This commit is contained in:
parent
24fb167ae6
commit
a515ad9b91
13 changed files with 576 additions and 1 deletions
|
|
@ -161,6 +161,7 @@ bindr=Super,Super_L,spawn,rofi -show run
|
||||||
| `reload_config` | - | Hot-reload configuration. |
|
| `reload_config` | - | Hot-reload configuration. |
|
||||||
| `quit` | - | Exit mangowm. |
|
| `quit` | - | Exit mangowm. |
|
||||||
| `toggleoverview` | - | Toggle overview mode. |
|
| `toggleoverview` | - | Toggle overview mode. |
|
||||||
|
| `togglejump` | - | Toggle overview with jump mode. |
|
||||||
| `create_virtual_output` | - | Create a headless monitor (for VNC/Sunshine). |
|
| `create_virtual_output` | - | Create a headless monitor (for VNC/Sunshine). |
|
||||||
| `destroy_all_virtual_output` | - | Destroy all virtual monitors. |
|
| `destroy_all_virtual_output` | - | Destroy all virtual monitors. |
|
||||||
| `toggleoverlay` | - | Toggle overlay state for the focused window. |
|
| `toggleoverlay` | - | Toggle overlay state for the focused window. |
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,7 @@ If your distribution isn't listed above, or you want the latest unreleased chang
|
||||||
> - `hwdata`
|
> - `hwdata`
|
||||||
> - `seatd`
|
> - `seatd`
|
||||||
> - `pcre2`
|
> - `pcre2`
|
||||||
|
> - `pango`
|
||||||
> - `cjson`
|
> - `cjson`
|
||||||
> - `pixman`
|
> - `pixman`
|
||||||
> - `xorg-xwayland`
|
> - `xorg-xwayland`
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,18 @@ You can also color-code windows based on their state:
|
||||||
|
|
||||||
> **Tip:** For scratchpad window sizing, see [Scratchpad](/docs/window-management/scratchpad) configuration.
|
> **Tip:** For scratchpad window sizing, see [Scratchpad](/docs/window-management/scratchpad) configuration.
|
||||||
|
|
||||||
|
### Overview Jump Mode
|
||||||
|
| Setting | Default | Description |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| `jump_hit_fg_color` | `0xc4939dff` | label text color. |
|
||||||
|
| `jump_hit_bg_color` | `0x201b14ff` | label background color.
|
||||||
|
| `jump_hit_border_color` | `0x8BAA9Bff` | label border color.
|
||||||
|
| `jump_hit_border_width` | `4` | label border width.
|
||||||
|
| `jump_hit_corner_radius` | `5` | label corner radius.
|
||||||
|
| `jump_hit_padding_x` | `10` | label horizontal padding.
|
||||||
|
| `jump_hit_padding_y` | `10` | label vertical padding.
|
||||||
|
| `jump_hit_font_desc` | `monospace Bold 24` | label font set.|
|
||||||
|
|
||||||
## Cursor Theme
|
## Cursor Theme
|
||||||
|
|
||||||
Set the size and theme of your mouse cursor.
|
Set the size and theme of your mouse cursor.
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
hwdata
|
hwdata
|
||||||
seatd
|
seatd
|
||||||
pcre2
|
pcre2
|
||||||
|
pango
|
||||||
cjson
|
cjson
|
||||||
libxcb
|
libxcb
|
||||||
pixman
|
pixman
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ pcre2_dep = dependency('libpcre2-8')
|
||||||
libscenefx_dep = dependency('scenefx-0.4',version: '>=0.4.1')
|
libscenefx_dep = dependency('scenefx-0.4',version: '>=0.4.1')
|
||||||
pixman_dep = dependency('pixman-1')
|
pixman_dep = dependency('pixman-1')
|
||||||
cjson_dep = dependency('libcjson')
|
cjson_dep = dependency('libcjson')
|
||||||
|
pangocairo_dep = dependency('pangocairo')
|
||||||
|
|
||||||
# version info
|
# version info
|
||||||
git = find_program('git', required : false)
|
git = find_program('git', required : false)
|
||||||
|
|
@ -94,6 +95,7 @@ endif
|
||||||
executable('mango',
|
executable('mango',
|
||||||
'src/mango.c',
|
'src/mango.c',
|
||||||
'src/common/util.c',
|
'src/common/util.c',
|
||||||
|
'src/draw/text-node.c',
|
||||||
'src/ext-protocol/wlr_ext_workspace_v1.c',
|
'src/ext-protocol/wlr_ext_workspace_v1.c',
|
||||||
wayland_sources,
|
wayland_sources,
|
||||||
dependencies : [
|
dependencies : [
|
||||||
|
|
@ -109,6 +111,7 @@ executable('mango',
|
||||||
pcre2_dep,
|
pcre2_dep,
|
||||||
pixman_dep,
|
pixman_dep,
|
||||||
cjson_dep,
|
cjson_dep,
|
||||||
|
pangocairo_dep,
|
||||||
],
|
],
|
||||||
install : true,
|
install : true,
|
||||||
c_args : c_args,
|
c_args : c_args,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
libxcb,
|
libxcb,
|
||||||
libxkbcommon,
|
libxkbcommon,
|
||||||
pcre2,
|
pcre2,
|
||||||
|
pango,
|
||||||
cjson,
|
cjson,
|
||||||
pixman,
|
pixman,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
|
|
@ -49,6 +50,7 @@ stdenv.mkDerivation {
|
||||||
libxcb
|
libxcb
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
pcre2
|
pcre2
|
||||||
|
pango
|
||||||
cjson
|
cjson
|
||||||
pixman
|
pixman
|
||||||
wayland
|
wayland
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,7 @@ typedef struct {
|
||||||
int32_t enable_hotarea;
|
int32_t enable_hotarea;
|
||||||
int32_t ov_tab_mode;
|
int32_t ov_tab_mode;
|
||||||
int32_t ov_no_resize;
|
int32_t ov_no_resize;
|
||||||
|
|
||||||
int32_t overviewgappi;
|
int32_t overviewgappi;
|
||||||
int32_t overviewgappo;
|
int32_t overviewgappo;
|
||||||
uint32_t cursor_hide_timeout;
|
uint32_t cursor_hide_timeout;
|
||||||
|
|
@ -407,6 +408,7 @@ typedef struct {
|
||||||
|
|
||||||
struct xkb_context *ctx;
|
struct xkb_context *ctx;
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
|
JumphitData jumhitdata;
|
||||||
} Config;
|
} Config;
|
||||||
|
|
||||||
typedef int32_t (*FuncType)(const Arg *);
|
typedef int32_t (*FuncType)(const Arg *);
|
||||||
|
|
@ -1030,6 +1032,9 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
||||||
} else if (strcmp(func_name, "toggleoverview") == 0) {
|
} else if (strcmp(func_name, "toggleoverview") == 0) {
|
||||||
func = toggleoverview;
|
func = toggleoverview;
|
||||||
(*arg).i = atoi(arg_value);
|
(*arg).i = atoi(arg_value);
|
||||||
|
} else if (strcmp(func_name, "togglejump") == 0) {
|
||||||
|
func = togglejump;
|
||||||
|
(*arg).i = atoi(arg_value);
|
||||||
} else if (strcmp(func_name, "set_proportion") == 0) {
|
} else if (strcmp(func_name, "set_proportion") == 0) {
|
||||||
func = set_proportion;
|
func = set_proportion;
|
||||||
(*arg).f = atof(arg_value);
|
(*arg).f = atof(arg_value);
|
||||||
|
|
@ -1758,6 +1763,50 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
config->cursor_size = atoi(value);
|
config->cursor_size = atoi(value);
|
||||||
} else if (strcmp(key, "cursor_theme") == 0) {
|
} else if (strcmp(key, "cursor_theme") == 0) {
|
||||||
config->cursor_theme = strdup(value);
|
config->cursor_theme = strdup(value);
|
||||||
|
} else if (strcmp(key, "jump_hit_fg_color") == 0) {
|
||||||
|
int64_t color = parse_color(value);
|
||||||
|
if (color == -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Invalid jump_hit_fg_color "
|
||||||
|
"format: %s\n",
|
||||||
|
value);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
convert_hex_to_rgba(config->jumhitdata.fg_color, color);
|
||||||
|
}
|
||||||
|
} else if (strcmp(key, "jump_hit_font_desc") == 0) {
|
||||||
|
config->jumhitdata.font_desc = strdup(value);
|
||||||
|
} else if (strcmp(key, "jump_hit_bg_color") == 0) {
|
||||||
|
int64_t color = parse_color(value);
|
||||||
|
if (color == -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Invalid jump_hit_bg_color "
|
||||||
|
"format: %s\n",
|
||||||
|
value);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
convert_hex_to_rgba(config->jumhitdata.bg_color, color);
|
||||||
|
}
|
||||||
|
} else if (strcmp(key, "jump_hit_border_color") == 0) {
|
||||||
|
int64_t color = parse_color(value);
|
||||||
|
if (color == -1) {
|
||||||
|
fprintf(
|
||||||
|
stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Invalid jump_hit_border_color "
|
||||||
|
"format: %s\n",
|
||||||
|
value);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
convert_hex_to_rgba(config->jumhitdata.border_color, color);
|
||||||
|
}
|
||||||
|
} else if (strcmp(key, "jump_hit_border_width") == 0) {
|
||||||
|
config->jumhitdata.border_width = CLAMP_INT(atoi(value), 0, 100);
|
||||||
|
} else if (strcmp(key, "jump_hit_corner_radius") == 0) {
|
||||||
|
config->jumhitdata.corner_radius = CLAMP_INT(atoi(value), 0, 100);
|
||||||
|
} else if (strcmp(key, "jump_hit_padding_x") == 0) {
|
||||||
|
config->jumhitdata.padding_x = CLAMP_INT(atoi(value), 0, 100);
|
||||||
|
} else if (strcmp(key, "jump_hit_padding_y") == 0) {
|
||||||
|
config->jumhitdata.padding_y = CLAMP_INT(atoi(value), 0, 100);
|
||||||
} else if (strcmp(key, "disable_while_typing") == 0) {
|
} else if (strcmp(key, "disable_while_typing") == 0) {
|
||||||
config->disable_while_typing = atoi(value);
|
config->disable_while_typing = atoi(value);
|
||||||
} else if (strcmp(key, "left_handed") == 0) {
|
} else if (strcmp(key, "left_handed") == 0) {
|
||||||
|
|
@ -3247,6 +3296,11 @@ void free_config(void) {
|
||||||
config.cursor_theme = NULL;
|
config.cursor_theme = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.jumhitdata.font_desc) {
|
||||||
|
free((void *)config.jumhitdata.font_desc);
|
||||||
|
config.jumhitdata.font_desc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (config.tablet_map_to_mon) {
|
if (config.tablet_map_to_mon) {
|
||||||
free(config.tablet_map_to_mon);
|
free(config.tablet_map_to_mon);
|
||||||
config.tablet_map_to_mon = NULL;
|
config.tablet_map_to_mon = NULL;
|
||||||
|
|
@ -3437,6 +3491,15 @@ void override_config(void) {
|
||||||
config.focused_opacity = CLAMP_FLOAT(config.focused_opacity, 0.0f, 1.0f);
|
config.focused_opacity = CLAMP_FLOAT(config.focused_opacity, 0.0f, 1.0f);
|
||||||
config.unfocused_opacity =
|
config.unfocused_opacity =
|
||||||
CLAMP_FLOAT(config.unfocused_opacity, 0.0f, 1.0f);
|
CLAMP_FLOAT(config.unfocused_opacity, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
config.jumhitdata.border_width =
|
||||||
|
CLAMP_INT(config.jumhitdata.border_width, 0, 100);
|
||||||
|
config.jumhitdata.corner_radius =
|
||||||
|
CLAMP_INT(config.jumhitdata.corner_radius, 0, 100);
|
||||||
|
config.jumhitdata.padding_x =
|
||||||
|
CLAMP_INT(config.jumhitdata.padding_x, 0, 100);
|
||||||
|
config.jumhitdata.padding_y =
|
||||||
|
CLAMP_INT(config.jumhitdata.padding_y, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_value_default() {
|
void set_value_default() {
|
||||||
|
|
@ -3475,7 +3538,6 @@ void set_value_default() {
|
||||||
config.log_level = WLR_ERROR;
|
config.log_level = WLR_ERROR;
|
||||||
config.numlockon = 0;
|
config.numlockon = 0;
|
||||||
config.capslock = 0;
|
config.capslock = 0;
|
||||||
|
|
||||||
config.ov_tab_mode = 1;
|
config.ov_tab_mode = 1;
|
||||||
config.ov_no_resize = 1;
|
config.ov_no_resize = 1;
|
||||||
config.hotarea_size = 10;
|
config.hotarea_size = 10;
|
||||||
|
|
@ -3613,6 +3675,23 @@ void set_value_default() {
|
||||||
config.animation_curve_opafadeout[2] = 0.5;
|
config.animation_curve_opafadeout[2] = 0.5;
|
||||||
config.animation_curve_opafadeout[3] = 0.5;
|
config.animation_curve_opafadeout[3] = 0.5;
|
||||||
|
|
||||||
|
config.jumhitdata.fg_color[0] = 0xc4 / 255.0f;
|
||||||
|
config.jumhitdata.fg_color[1] = 0x93 / 255.0f;
|
||||||
|
config.jumhitdata.fg_color[2] = 0x9d / 255.0f;
|
||||||
|
config.jumhitdata.fg_color[3] = 1.0f;
|
||||||
|
config.jumhitdata.bg_color[0] = 0x32 / 255.0f;
|
||||||
|
config.jumhitdata.bg_color[1] = 0x32 / 255.0f;
|
||||||
|
config.jumhitdata.bg_color[2] = 0x32 / 255.0f;
|
||||||
|
config.jumhitdata.bg_color[3] = 1.0f;
|
||||||
|
config.jumhitdata.border_color[0] = 0x8b / 255.0f;
|
||||||
|
config.jumhitdata.border_color[1] = 0xaa / 255.0f;
|
||||||
|
config.jumhitdata.border_color[2] = 0x9b / 255.0f;
|
||||||
|
config.jumhitdata.border_color[3] = 1.0f;
|
||||||
|
config.jumhitdata.border_width = 4;
|
||||||
|
config.jumhitdata.corner_radius = 5;
|
||||||
|
config.jumhitdata.padding_x = 10;
|
||||||
|
config.jumhitdata.padding_y = 10;
|
||||||
|
|
||||||
config.rootcolor[0] = 0x32 / 255.0f;
|
config.rootcolor[0] = 0x32 / 255.0f;
|
||||||
config.rootcolor[1] = 0x32 / 255.0f;
|
config.rootcolor[1] = 0x32 / 255.0f;
|
||||||
config.rootcolor[2] = 0x32 / 255.0f;
|
config.rootcolor[2] = 0x32 / 255.0f;
|
||||||
|
|
@ -3725,6 +3804,7 @@ bool parse_config(void) {
|
||||||
config.tag_rules = NULL;
|
config.tag_rules = NULL;
|
||||||
config.tag_rules_count = 0;
|
config.tag_rules_count = 0;
|
||||||
config.cursor_theme = NULL;
|
config.cursor_theme = NULL;
|
||||||
|
config.jumhitdata.font_desc = NULL;
|
||||||
config.tablet_map_to_mon = NULL;
|
config.tablet_map_to_mon = NULL;
|
||||||
strcpy(config.keymode, "default");
|
strcpy(config.keymode, "default");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ int32_t restore_minimized(const Arg *arg);
|
||||||
int32_t toggle_scratchpad(const Arg *arg);
|
int32_t toggle_scratchpad(const Arg *arg);
|
||||||
int32_t focusdir(const Arg *arg);
|
int32_t focusdir(const Arg *arg);
|
||||||
int32_t toggleoverview(const Arg *arg);
|
int32_t toggleoverview(const Arg *arg);
|
||||||
|
int32_t togglejump(const Arg *arg);
|
||||||
int32_t set_proportion(const Arg *arg);
|
int32_t set_proportion(const Arg *arg);
|
||||||
int32_t switch_proportion_preset(const Arg *arg);
|
int32_t switch_proportion_preset(const Arg *arg);
|
||||||
int32_t zoom(const Arg *arg);
|
int32_t zoom(const Arg *arg);
|
||||||
|
|
|
||||||
|
|
@ -1737,6 +1737,10 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
uint32_t target;
|
uint32_t target;
|
||||||
uint32_t visible_client_number = 0;
|
uint32_t visible_client_number = 0;
|
||||||
|
|
||||||
|
if (!selmon->isoverview && selmon->is_jump_mode) {
|
||||||
|
finish_jump_mode(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
if (selmon->isoverview) {
|
if (selmon->isoverview) {
|
||||||
wl_list_for_each(c, &clients, link) if (c && c->mon == selmon &&
|
wl_list_for_each(c, &clients, link) if (c && c->mon == selmon &&
|
||||||
!client_is_unmanaged(c) &&
|
!client_is_unmanaged(c) &&
|
||||||
|
|
@ -1781,6 +1785,7 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
selmon->tagset[selmon->seltags] = target;
|
selmon->tagset[selmon->seltags] = target;
|
||||||
wl_list_for_each(c, &clients, link) {
|
wl_list_for_each(c, &clients, link) {
|
||||||
if (c && c->mon == selmon && !c->iskilling &&
|
if (c && c->mon == selmon && !c->iskilling &&
|
||||||
|
|
@ -1794,6 +1799,24 @@ int32_t toggleoverview(const Arg *arg) {
|
||||||
view(&(Arg){.ui = target}, false);
|
view(&(Arg){.ui = target}, false);
|
||||||
fix_mon_tagset_from_overview(selmon);
|
fix_mon_tagset_from_overview(selmon);
|
||||||
refresh_monitors_workspaces_status(selmon);
|
refresh_monitors_workspaces_status(selmon);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t togglejump(const Arg *arg) {
|
||||||
|
if (!selmon)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!selmon->isoverview) {
|
||||||
|
begin_jump_mode(selmon);
|
||||||
|
toggleoverview(arg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selmon->isoverview) {
|
||||||
|
toggleoverview(arg);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
308
src/draw/text-node.c
Normal file
308
src/draw/text-node.c
Normal file
|
|
@ -0,0 +1,308 @@
|
||||||
|
#include "text-node.h"
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <drm_fourcc.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/interfaces/wlr_buffer.h>
|
||||||
|
|
||||||
|
// 自定义 wlr_buffer,用于将 Cairo Surface 包装并注入 wlr_scene
|
||||||
|
struct mango_text_buffer {
|
||||||
|
struct wlr_buffer base;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全局字体描述缓存
|
||||||
|
static GHashTable *font_desc_cache = NULL;
|
||||||
|
|
||||||
|
static PangoFontDescription *get_cached_font_desc(const char *font_desc) {
|
||||||
|
if (!font_desc_cache) {
|
||||||
|
font_desc_cache =
|
||||||
|
g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||||
|
(GDestroyNotify)pango_font_description_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
PangoFontDescription *desc =
|
||||||
|
g_hash_table_lookup(font_desc_cache, font_desc);
|
||||||
|
if (!desc) {
|
||||||
|
desc = pango_font_description_from_string(font_desc);
|
||||||
|
g_hash_table_insert(font_desc_cache, g_strdup(font_desc), desc);
|
||||||
|
}
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_global_finish(void) {
|
||||||
|
if (font_desc_cache) {
|
||||||
|
g_hash_table_destroy(font_desc_cache);
|
||||||
|
font_desc_cache = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wlr_buffer 实现
|
||||||
|
static void text_buffer_destroy(struct wlr_buffer *wlr_buffer) {
|
||||||
|
struct mango_text_buffer *buf = wl_container_of(wlr_buffer, buf, base);
|
||||||
|
cairo_surface_destroy(buf->surface);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool text_buffer_begin_data_ptr_access(struct wlr_buffer *wlr_buffer,
|
||||||
|
uint32_t flags, void **data,
|
||||||
|
uint32_t *format,
|
||||||
|
size_t *stride) {
|
||||||
|
(void)flags;
|
||||||
|
struct mango_text_buffer *buf = wl_container_of(wlr_buffer, buf, base);
|
||||||
|
*data = cairo_image_surface_get_data(buf->surface);
|
||||||
|
*format = DRM_FORMAT_ARGB8888;
|
||||||
|
*stride = cairo_image_surface_get_stride(buf->surface);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void text_buffer_end_data_ptr_access(struct wlr_buffer *wlr_buffer) {}
|
||||||
|
|
||||||
|
static const struct wlr_buffer_impl text_buffer_impl = {
|
||||||
|
.destroy = text_buffer_destroy,
|
||||||
|
.begin_data_ptr_access = text_buffer_begin_data_ptr_access,
|
||||||
|
.end_data_ptr_access = text_buffer_end_data_ptr_access,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mango_text_node *mango_text_node_create(struct wlr_scene_tree *parent,
|
||||||
|
JumphitData data) {
|
||||||
|
struct mango_text_node *node = calloc(1, sizeof(*node));
|
||||||
|
if (!node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
node->scene_buffer = wlr_scene_buffer_create(parent, NULL);
|
||||||
|
if (!node->scene_buffer) {
|
||||||
|
free(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->fg_color[0] = data.fg_color[0];
|
||||||
|
node->fg_color[1] = data.fg_color[1];
|
||||||
|
node->fg_color[2] = data.fg_color[2];
|
||||||
|
node->fg_color[3] = data.fg_color[3];
|
||||||
|
node->bg_color[0] = data.bg_color[0];
|
||||||
|
node->bg_color[1] = data.bg_color[1];
|
||||||
|
node->bg_color[2] = data.bg_color[2];
|
||||||
|
node->bg_color[3] = data.bg_color[3];
|
||||||
|
node->border_color[0] = data.border_color[0];
|
||||||
|
node->border_color[1] = data.border_color[1];
|
||||||
|
node->border_color[2] = data.border_color[2];
|
||||||
|
node->border_color[3] = data.border_color[3];
|
||||||
|
node->border_width = data.border_width;
|
||||||
|
node->corner_radius = data.corner_radius;
|
||||||
|
node->padding_x = data.padding_x;
|
||||||
|
node->padding_y = data.padding_y;
|
||||||
|
node->font_desc = data.font_desc ? data.font_desc : "monospace Bold 24";
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_node_destroy(struct mango_text_node *node) {
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlr_scene_node_destroy(&node->scene_buffer->node);
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_node_set_background(struct mango_text_node *node, float r,
|
||||||
|
float g, float b, float a) {
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
node->bg_color[0] = r;
|
||||||
|
node->bg_color[1] = g;
|
||||||
|
node->bg_color[2] = b;
|
||||||
|
node->bg_color[3] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
||||||
|
float b, float a, float width, float radius) {
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
node->border_color[0] = r;
|
||||||
|
node->border_color[1] = g;
|
||||||
|
node->border_color[2] = b;
|
||||||
|
node->border_color[3] = a;
|
||||||
|
node->border_width = width > 0.0f ? width : 0.0f;
|
||||||
|
node->corner_radius = radius >= 0.0f ? radius : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_node_set_padding(struct mango_text_node *node, float pad_x,
|
||||||
|
float pad_y) {
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
node->padding_x = pad_x >= 0.0f ? pad_x : 0.0f;
|
||||||
|
node->padding_y = pad_y >= 0.0f ? pad_y : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_rounded_rect(cairo_t *cr, double x, double y, double w,
|
||||||
|
double h, double r) {
|
||||||
|
// 使用 Cairo 的标准圆角矩形路径
|
||||||
|
double degrees = G_PI / 180.0;
|
||||||
|
cairo_new_sub_path(cr);
|
||||||
|
cairo_arc(cr, x + w - r, y + r, r, -90 * degrees, 0 * degrees);
|
||||||
|
cairo_arc(cr, x + w - r, y + h - r, r, 0 * degrees, 90 * degrees);
|
||||||
|
cairo_arc(cr, x + r, y + h - r, r, 90 * degrees, 180 * degrees);
|
||||||
|
cairo_arc(cr, x + r, y + r, r, 180 * degrees, 270 * degrees);
|
||||||
|
cairo_close_path(cr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
|
|
||||||
|
float scale) {
|
||||||
|
if (!node || !text)
|
||||||
|
return;
|
||||||
|
if (scale <= 0.0f)
|
||||||
|
scale = 1.0f;
|
||||||
|
|
||||||
|
const char *font_desc = node->font_desc;
|
||||||
|
PangoFontDescription *desc = get_cached_font_desc(font_desc);
|
||||||
|
|
||||||
|
// 测量文字像素尺寸(无缩放的实际像素)
|
||||||
|
cairo_surface_t *dummy_surface =
|
||||||
|
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
|
||||||
|
cairo_t *dummy_cr = cairo_create(dummy_surface);
|
||||||
|
PangoContext *dummy_ctx = pango_cairo_create_context(dummy_cr);
|
||||||
|
pango_cairo_context_set_resolution(dummy_ctx, 96.0 * scale);
|
||||||
|
PangoLayout *dummy_layout = pango_layout_new(dummy_ctx);
|
||||||
|
pango_layout_set_font_description(dummy_layout, desc);
|
||||||
|
pango_layout_set_text(dummy_layout, text, -1);
|
||||||
|
|
||||||
|
int text_pixel_w, text_pixel_h;
|
||||||
|
pango_layout_get_pixel_size(dummy_layout, &text_pixel_w, &text_pixel_h);
|
||||||
|
|
||||||
|
g_object_unref(dummy_layout);
|
||||||
|
g_object_unref(dummy_ctx);
|
||||||
|
cairo_destroy(dummy_cr);
|
||||||
|
cairo_surface_destroy(dummy_surface);
|
||||||
|
|
||||||
|
if (text_pixel_w <= 0 || text_pixel_h <= 0) {
|
||||||
|
wlr_scene_buffer_set_buffer(node->scene_buffer, NULL);
|
||||||
|
node->logical_width = 0;
|
||||||
|
node->logical_height = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float logical_text_w = text_pixel_w / scale;
|
||||||
|
float logical_text_h = text_pixel_h / scale;
|
||||||
|
|
||||||
|
float pad_x = node->padding_x;
|
||||||
|
float pad_y = node->padding_y;
|
||||||
|
float box_logical_w = logical_text_w + 2.0f * pad_x;
|
||||||
|
float box_logical_h = logical_text_h + 2.0f * pad_y;
|
||||||
|
|
||||||
|
float border = node->border_width;
|
||||||
|
bool draw_border = (border > 0.0f) && (node->border_color[3] > 0.0f);
|
||||||
|
bool draw_bg = (node->bg_color[3] > 0.0f);
|
||||||
|
|
||||||
|
int surface_pixel_w = (int)((box_logical_w + 2.0f * border) * scale + 0.5f);
|
||||||
|
int surface_pixel_h = (int)((box_logical_h + 2.0f * border) * scale + 0.5f);
|
||||||
|
|
||||||
|
if (surface_pixel_w < 1)
|
||||||
|
surface_pixel_w = 1;
|
||||||
|
if (surface_pixel_h < 1)
|
||||||
|
surface_pixel_h = 1;
|
||||||
|
|
||||||
|
cairo_surface_t *surface = cairo_image_surface_create(
|
||||||
|
CAIRO_FORMAT_ARGB32, surface_pixel_w, surface_pixel_h);
|
||||||
|
cairo_t *cr = cairo_create(surface);
|
||||||
|
|
||||||
|
// 清空为全透明
|
||||||
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||||
|
cairo_paint(cr);
|
||||||
|
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
||||||
|
|
||||||
|
double bg_x = border * scale;
|
||||||
|
double bg_y = border * scale;
|
||||||
|
double bg_w = box_logical_w * scale;
|
||||||
|
double bg_h = box_logical_h * scale;
|
||||||
|
|
||||||
|
double radius = node->corner_radius * scale;
|
||||||
|
|
||||||
|
if (radius < 0) {
|
||||||
|
radius = (bg_w < bg_h ? bg_w : bg_h) / 2.0;
|
||||||
|
}
|
||||||
|
if (radius > bg_w / 2.0)
|
||||||
|
radius = bg_w / 2.0;
|
||||||
|
if (radius > bg_h / 2.0)
|
||||||
|
radius = bg_h / 2.0;
|
||||||
|
|
||||||
|
if (draw_bg) {
|
||||||
|
cairo_set_source_rgba(cr, node->bg_color[0], node->bg_color[1],
|
||||||
|
node->bg_color[2], node->bg_color[3]);
|
||||||
|
if (radius > 0.0) {
|
||||||
|
draw_rounded_rect(cr, bg_x, bg_y, bg_w, bg_h, radius);
|
||||||
|
cairo_fill(cr);
|
||||||
|
} else {
|
||||||
|
cairo_rectangle(cr, bg_x, bg_y, bg_w, bg_h);
|
||||||
|
cairo_fill(cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_save(cr);
|
||||||
|
cairo_translate(cr, (border + pad_x) * scale, (border + pad_y) * scale);
|
||||||
|
|
||||||
|
PangoContext *ctx = pango_cairo_create_context(cr);
|
||||||
|
pango_cairo_context_set_resolution(ctx, 96.0 * scale);
|
||||||
|
PangoLayout *layout = pango_layout_new(ctx);
|
||||||
|
pango_layout_set_font_description(layout, desc);
|
||||||
|
pango_layout_set_text(layout, text, -1);
|
||||||
|
|
||||||
|
cairo_set_source_rgba(cr, node->fg_color[0], node->fg_color[1],
|
||||||
|
node->fg_color[2], node->fg_color[3]);
|
||||||
|
pango_cairo_show_layout(cr, layout);
|
||||||
|
|
||||||
|
g_object_unref(layout);
|
||||||
|
g_object_unref(ctx);
|
||||||
|
cairo_restore(cr);
|
||||||
|
|
||||||
|
if (draw_border) {
|
||||||
|
cairo_set_source_rgba(cr, node->border_color[0], node->border_color[1],
|
||||||
|
node->border_color[2], node->border_color[3]);
|
||||||
|
cairo_set_line_width(cr, border * scale);
|
||||||
|
|
||||||
|
double half_lw = border * scale * 0.5;
|
||||||
|
double bx = bg_x - half_lw;
|
||||||
|
double by = bg_y - half_lw;
|
||||||
|
double bw = bg_w + border * scale;
|
||||||
|
double bh = bg_h + border * scale;
|
||||||
|
|
||||||
|
if (radius > 0.0) {
|
||||||
|
double outer_radius = radius + half_lw;
|
||||||
|
if (outer_radius < 0.0)
|
||||||
|
outer_radius = 0.0;
|
||||||
|
draw_rounded_rect(cr, bx, by, bw, bh, outer_radius);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
} else {
|
||||||
|
cairo_rectangle(cr, bx, by, bw, bh);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_flush(surface);
|
||||||
|
|
||||||
|
// 包装成 wlr_buffer
|
||||||
|
struct mango_text_buffer *buf = calloc(1, sizeof(*buf));
|
||||||
|
if (!buf) {
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
cairo_destroy(cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wlr_buffer_init(&buf->base, &text_buffer_impl, surface_pixel_w,
|
||||||
|
surface_pixel_h);
|
||||||
|
buf->surface = surface;
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_buffer(node->scene_buffer, &buf->base);
|
||||||
|
wlr_buffer_drop(&buf->base);
|
||||||
|
|
||||||
|
// 最终逻辑大小 = 背景框逻辑尺寸 + 边框逻辑尺寸
|
||||||
|
node->logical_width = (int)(box_logical_w + 2.0f * border);
|
||||||
|
node->logical_height = (int)(box_logical_h + 2.0f * border);
|
||||||
|
wlr_scene_buffer_set_dest_size(node->scene_buffer, node->logical_width,
|
||||||
|
node->logical_height);
|
||||||
|
|
||||||
|
cairo_destroy(cr);
|
||||||
|
}
|
||||||
52
src/draw/text-node.h
Normal file
52
src/draw/text-node.h
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#ifndef MANGO_TEXT_NODE_H
|
||||||
|
#define MANGO_TEXT_NODE_H
|
||||||
|
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
|
||||||
|
struct mango_text_node {
|
||||||
|
struct wlr_scene_buffer *scene_buffer;
|
||||||
|
int logical_width;
|
||||||
|
int logical_height;
|
||||||
|
const char *font_desc;
|
||||||
|
|
||||||
|
// 外观属性
|
||||||
|
float fg_color[4]; // 文本颜色 RGBA,默认白色
|
||||||
|
float bg_color[4]; // 背景色 RGBA,默认透明
|
||||||
|
float border_color[4]; // 边框色 RGBA,默认透明
|
||||||
|
int32_t border_width; // 边框宽度(逻辑像素),<=0 则不绘制
|
||||||
|
int32_t corner_radius; // 圆角半径(逻辑像素),<0 时自动取
|
||||||
|
// min(width,height)/2 形成胶囊
|
||||||
|
int32_t padding_x; // 文本左右内边距(逻辑像素)
|
||||||
|
int32_t padding_y; // 文本上下内边距(逻辑像素)
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float fg_color[4];
|
||||||
|
float bg_color[4];
|
||||||
|
float border_color[4];
|
||||||
|
int32_t border_width;
|
||||||
|
int32_t corner_radius;
|
||||||
|
int32_t padding_x;
|
||||||
|
int32_t padding_y;
|
||||||
|
const char *font_desc;
|
||||||
|
} JumphitData;
|
||||||
|
|
||||||
|
struct mango_text_node *mango_text_node_create(struct wlr_scene_tree *parent,
|
||||||
|
JumphitData data);
|
||||||
|
void mango_text_node_destroy(struct mango_text_node *node);
|
||||||
|
void mango_text_node_update(struct mango_text_node *node, const char *text,
|
||||||
|
float scale);
|
||||||
|
|
||||||
|
// 外观设置接口
|
||||||
|
void mango_text_node_set_background(struct mango_text_node *node, float r,
|
||||||
|
float g, float b, float a);
|
||||||
|
void mango_text_node_set_border(struct mango_text_node *node, float r, float g,
|
||||||
|
float b, float a, float width, float radius);
|
||||||
|
void mango_text_node_set_padding(struct mango_text_node *node, float pad_x,
|
||||||
|
float pad_y);
|
||||||
|
|
||||||
|
void mango_text_node_destroy(struct mango_text_node *node);
|
||||||
|
void mango_text_global_finish(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -353,10 +353,65 @@ void overview_resize(Monitor *m) {
|
||||||
free(c_arr);
|
free(c_arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void create_jump_hints(Monitor *m) {
|
||||||
|
const char jump_labels[] = "HJKLASDFGQWERTYUIOPZXCVBNM";
|
||||||
|
int label_idx = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, m) &&
|
||||||
|
((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) {
|
||||||
|
if (label_idx >= 26)
|
||||||
|
break;
|
||||||
|
char c_char = jump_labels[label_idx];
|
||||||
|
c->jump_char = c_char;
|
||||||
|
|
||||||
|
// 把字符变成字符串
|
||||||
|
char label_text[2] = {c_char, '\0'};
|
||||||
|
|
||||||
|
mango_text_node_update(c->text_node, label_text, 1.0f);
|
||||||
|
wlr_scene_node_set_enabled(&c->text_node->scene_buffer->node, true);
|
||||||
|
wlr_scene_node_raise_to_top(&c->text_node->scene_buffer->node);
|
||||||
|
wlr_scene_node_set_position(
|
||||||
|
&c->text_node->scene_buffer->node,
|
||||||
|
c->geom.width / 2 - c->text_node->logical_width / 2,
|
||||||
|
c->geom.height / 2 - c->text_node->logical_height / 2);
|
||||||
|
label_idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void begin_jump_mode(Monitor *m) { m->is_jump_mode = 1; }
|
||||||
|
|
||||||
|
void finish_jump_mode(Monitor *m) {
|
||||||
|
Client *c = NULL;
|
||||||
|
|
||||||
|
if (!m->is_jump_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (VISIBLEON(c, m)) {
|
||||||
|
if (c->text_node->scene_buffer->node.enabled) {
|
||||||
|
c->jump_char = '\0';
|
||||||
|
wlr_scene_node_set_enabled(&c->text_node->scene_buffer->node,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m->is_jump_mode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void overview(Monitor *m) {
|
void overview(Monitor *m) {
|
||||||
|
|
||||||
if (config.ov_no_resize) {
|
if (config.ov_no_resize) {
|
||||||
overview_scale(m);
|
overview_scale(m);
|
||||||
} else {
|
} else {
|
||||||
overview_resize(m);
|
overview_resize(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m->is_jump_mode) {
|
||||||
|
create_jump_hints(m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
36
src/mango.c
36
src/mango.c
|
|
@ -96,6 +96,7 @@
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
#endif
|
#endif
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "draw/text-node.h"
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
|
|
@ -327,6 +328,7 @@ struct Client {
|
||||||
struct wlr_scene_shadow *shadow;
|
struct wlr_scene_shadow *shadow;
|
||||||
struct wlr_scene_tree *scene_surface;
|
struct wlr_scene_tree *scene_surface;
|
||||||
struct wlr_scene_tree *overview_scene_surface;
|
struct wlr_scene_tree *overview_scene_surface;
|
||||||
|
struct mango_text_node *text_node;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list flink;
|
struct wl_list flink;
|
||||||
struct wl_list fadeout_link;
|
struct wl_list fadeout_link;
|
||||||
|
|
@ -433,6 +435,7 @@ struct Client {
|
||||||
int32_t allow_shortcuts_inhibit;
|
int32_t allow_shortcuts_inhibit;
|
||||||
float scroller_proportion_single;
|
float scroller_proportion_single;
|
||||||
bool isfocusing;
|
bool isfocusing;
|
||||||
|
char jump_char;
|
||||||
bool enable_drop_area_draw;
|
bool enable_drop_area_draw;
|
||||||
int32_t drop_direction;
|
int32_t drop_direction;
|
||||||
struct wlr_box drag_tile_float_backup_geom;
|
struct wlr_box drag_tile_float_backup_geom;
|
||||||
|
|
@ -554,6 +557,7 @@ struct Monitor {
|
||||||
uint32_t ovbk_prev_tagset;
|
uint32_t ovbk_prev_tagset;
|
||||||
Client *sel, *prevsel;
|
Client *sel, *prevsel;
|
||||||
int32_t isoverview;
|
int32_t isoverview;
|
||||||
|
int32_t is_jump_mode;
|
||||||
int32_t is_in_hotarea;
|
int32_t is_in_hotarea;
|
||||||
int32_t asleep;
|
int32_t asleep;
|
||||||
uint32_t visible_clients;
|
uint32_t visible_clients;
|
||||||
|
|
@ -899,6 +903,10 @@ Client *scroll_get_stack_tail_client(Client *c);
|
||||||
static DwindleNode *dwindle_find_leaf(DwindleNode *node, Client *c);
|
static DwindleNode *dwindle_find_leaf(DwindleNode *node, Client *c);
|
||||||
static void overview_backup_surface(Client *c);
|
static void overview_backup_surface(Client *c);
|
||||||
|
|
||||||
|
static void create_jump_hints(Monitor *m);
|
||||||
|
static void finish_jump_mode(Monitor *m);
|
||||||
|
static void begin_jump_mode(Monitor *m);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
#include "layout/layout.h"
|
#include "layout/layout.h"
|
||||||
|
|
@ -2561,6 +2569,8 @@ void cleanup(void) {
|
||||||
/* Destroy after the wayland display (when the monitors are already
|
/* Destroy after the wayland display (when the monitors are already
|
||||||
destroyed) to avoid destroying them with an invalid scene output. */
|
destroyed) to avoid destroying them with an invalid scene output. */
|
||||||
wlr_scene_node_destroy(&scene->tree.node);
|
wlr_scene_node_destroy(&scene->tree.node);
|
||||||
|
|
||||||
|
mango_text_global_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanupmon(struct wl_listener *listener, void *data) {
|
void cleanupmon(struct wl_listener *listener, void *data) {
|
||||||
|
|
@ -4254,6 +4264,27 @@ void keypress(struct wl_listener *listener, void *data) {
|
||||||
if (handled)
|
if (handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (selmon && selmon->is_jump_mode &&
|
||||||
|
event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
for (i = 0; i < nsyms; i++) {
|
||||||
|
xkb_keysym_t sym = xkb_keysym_to_lower(syms[i]);
|
||||||
|
if (sym >= XKB_KEY_a && sym <= XKB_KEY_z) {
|
||||||
|
char c_char = 'A' + (sym - XKB_KEY_a);
|
||||||
|
Client *c;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (c->mon == selmon && c->jump_char == c_char) {
|
||||||
|
focusclient(c, 1);
|
||||||
|
toggleoverview(&(Arg){.i = 1});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sym == XKB_KEY_Escape) {
|
||||||
|
togglejump(&(Arg){.i = 0});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* don't pass when popup is focused
|
/* don't pass when popup is focused
|
||||||
* this is better than having popups (like fuzzel or wmenu) closing
|
* this is better than having popups (like fuzzel or wmenu) closing
|
||||||
* while typing in a passed keybind */
|
* while typing in a passed keybind */
|
||||||
|
|
@ -4513,6 +4544,10 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
#endif
|
#endif
|
||||||
// extra node
|
// extra node
|
||||||
|
|
||||||
|
c->text_node = mango_text_node_create(c->scene, config.jumhitdata);
|
||||||
|
wlr_scene_node_lower_to_bottom(&c->text_node->scene_buffer->node);
|
||||||
|
wlr_scene_node_set_enabled(&c->text_node->scene_buffer->node, false);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
c->splitindicator[i] = wlr_scene_rect_create(
|
c->splitindicator[i] = wlr_scene_rect_create(
|
||||||
c->scene, 0, 0,
|
c->scene, 0, 0,
|
||||||
|
|
@ -6510,6 +6545,7 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
||||||
|
|
||||||
c->stack_proportion = 0.0f;
|
c->stack_proportion = 0.0f;
|
||||||
|
|
||||||
|
mango_text_node_destroy(c->text_node);
|
||||||
wlr_scene_node_destroy(&c->scene->node);
|
wlr_scene_node_destroy(&c->scene->node);
|
||||||
printstatus(IPC_WATCH_ARRANGGE);
|
printstatus(IPC_WATCH_ARRANGGE);
|
||||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue