feat: monocle layout support title tab

This commit is contained in:
DreamMaoMao 2026-06-17 10:22:37 +08:00
parent 5652066c68
commit 5a60f39064
12 changed files with 843 additions and 133 deletions

View file

@ -169,6 +169,7 @@ enum {
LyrBg,
LyrBlur,
LyrBottom,
LyrDecorate,
LyrTile,
LyrTop,
LyrFadeOut,
@ -177,6 +178,9 @@ enum {
LyrBlock,
NUM_LAYERS
}; /* scene layers */
enum mango_node_type { MANGO_TITLE_NODE, MANGO_TEXT_NODE };
#ifdef XWAYLAND
enum {
NetWMWindowTypeDialog,
@ -243,6 +247,11 @@ typedef struct {
Client *tc;
} Arg;
typedef struct {
enum mango_node_type type;
void *node_data;
} MangoNodeData;
typedef struct {
uint32_t mod;
uint32_t button;
@ -266,8 +275,8 @@ typedef struct {
struct wl_list link;
struct wlr_input_device *wlr_device;
struct libinput_device *libinput_device;
struct wl_listener destroy_listener; // 用于监听设备销毁事件
void *device_data; // 新增:指向设备特定数据(如 Switch
struct wl_listener destroy_listener;
void *device_data;
} InputDevice;
typedef struct {
@ -329,6 +338,7 @@ struct Client {
struct wlr_scene_tree *scene_surface;
struct wlr_scene_tree *overview_scene_surface;
struct mango_text_node *text_node;
struct mango_titlebar_node *titlebar_node;
struct wl_list link;
struct wl_list flink;
struct wl_list fadeout_link;
@ -396,6 +406,7 @@ struct Client {
int32_t iskilling;
int32_t istagswitching;
int32_t isnamedscratchpad;
bool is_monocle_hide;
bool is_pending_open_animation;
bool is_restoring_from_ov;
float scroller_proportion;
@ -841,6 +852,7 @@ static struct wlr_scene_tree *
wlr_scene_tree_snapshot(struct wlr_scene_node *node,
struct wlr_scene_tree *parent);
static bool is_scroller_layout(Monitor *m);
static bool is_monocle_layout(Monitor *m);
static bool is_centertile_layout(Monitor *m);
static void create_output(struct wlr_backend *backend, void *data);
static void get_layout_abbr(char *abbr, const char *full_name);
@ -1262,6 +1274,11 @@ void swallow(Client *c, Client *w) {
overview_backup_surface(c);
}
if (w->titlebar_node) {
wlr_scene_node_set_enabled(&w->titlebar_node->scene_buffer->node,
false);
}
/* 全局链表替换 */
wl_list_insert(&w->link, &c->link);
wl_list_insert(&w->flink, &c->flink);
@ -2371,6 +2388,17 @@ bool handle_buttonpress(struct wlr_pointer_button_event *event) {
return true;
}
// handle click on tile node
struct wlr_scene_node *node = wlr_scene_node_at(
&layers[LyrDecorate]->node, cursor->x, cursor->y, NULL, NULL);
if (node && node->data) {
MangoNodeData *mangonodedata = (MangoNodeData *)node->data;
if (mangonodedata->type == MANGO_TITLE_NODE) {
Client *c = mangonodedata->node_data;
focusclient(c, 1);
}
}
// 当鼠标焦点在layer上的时候不检测虚拟键盘的mod状态
// 避免layer虚拟键盘锁死mod按键状态
hard_keyboard = &kb_group->wlr_group->keyboard;
@ -3857,17 +3885,17 @@ void focusclient(Client *c, int32_t lift) {
// decide whether need to re-arrange
if (c && selmon->prevsel &&
(selmon->prevsel->tags & selmon->tagset[selmon->seltags]) &&
(c->tags & selmon->tagset[selmon->seltags]) && !c->isfloating &&
is_scroller_layout(selmon)) {
arrange(selmon, false, false);
}
// change focus link position
wl_list_remove(&c->flink);
wl_list_insert(&fstack, &c->flink);
if (c && selmon->prevsel &&
(selmon->prevsel->tags & selmon->tagset[selmon->seltags]) &&
(c->tags & selmon->tagset[selmon->seltags]) && !c->isfloating &&
(is_scroller_layout(selmon) || is_monocle_layout(selmon))) {
arrange(selmon, false, false);
}
// change border color
c->isurgent = 0;
}
@ -4394,6 +4422,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
void init_client_properties(Client *c) {
c->grid_col_per = 1.0f;
c->grid_row_per = 1.0f;
c->is_monocle_hide = false;
c->overview_scene_surface = NULL;
c->drop_direction = UNDIR;
c->enable_drop_area_draw = false;
@ -4544,10 +4573,6 @@ mapnotify(struct wl_listener *listener, void *data) {
#endif
// 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++) {
c->splitindicator[i] = wlr_scene_rect_create(
c->scene, 0, 0,
@ -6546,6 +6571,7 @@ void unmapnotify(struct wl_listener *listener, void *data) {
c->stack_proportion = 0.0f;
mango_text_node_destroy(c->text_node);
mango_titlebar_node_destroy(c->titlebar_node);
wlr_scene_node_destroy(&c->scene->node);
printstatus(IPC_WATCH_ARRANGGE);
motionnotify(0, NULL, 0, 0, 0, 0);
@ -6698,6 +6724,7 @@ void updatetitle(struct wl_listener *listener, void *data) {
const char *title;
title = client_get_title(c);
mango_titlebar_node_update(c->titlebar_node, title, 1.0);
if (title && c->foreign_toplevel)
wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title);
if (c == focustop(c->mon))