添加 monocle 布局功能
This commit is contained in:
@@ -39,6 +39,7 @@ add_executable(${APP_NAME}
|
||||
${SOURCE_DIR}/action.c
|
||||
${SOURCE_DIR}/xkb.c
|
||||
${SOURCE_DIR}/atoms.c
|
||||
${SOURCE_DIR}/layout.c
|
||||
)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
|
||||
38
src/client.c
38
src/client.c
@@ -1,5 +1,6 @@
|
||||
#include "client.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
@@ -48,6 +49,13 @@ static void client_detach_stack(client_t *client) {
|
||||
}
|
||||
}
|
||||
|
||||
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag) {
|
||||
for (task_in_tag_t *task = tag->task_list; task; task = task->next) {
|
||||
if (task->client == client) return task;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void client_manage(xcb_window_t window,
|
||||
xcb_get_geometry_reply_t *geometry_reply) {
|
||||
client_t *c = p_new(client_t, 1);
|
||||
@@ -104,6 +112,36 @@ void client_manage(xcb_window_t window,
|
||||
xcb_flush(wm.xcb_conn);
|
||||
}
|
||||
|
||||
bool client_need_layout(client_t *client) {
|
||||
if (client->floating || client->fullscreen || client->maximize ||
|
||||
client->minimize) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void client_move_to(client_t *client, int16_t x, int16_t y) {
|
||||
client->geometry.x = x;
|
||||
client->geometry.y = y;
|
||||
uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
|
||||
const xcb_params_configure_window_t params = {.x = x, .y = y};
|
||||
xcb_aux_configure_window(wm.xcb_conn, client->window, mask, ¶ms);
|
||||
logger("== client 0x%x move to x: %d, y: %d\n", client->window, x, y);
|
||||
}
|
||||
|
||||
void client_resize(client_t *client, uint16_t width, uint16_t height) {
|
||||
client->geometry.width = width;
|
||||
client->geometry.height = height;
|
||||
uint16_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||
const xcb_params_configure_window_t params = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
xcb_aux_configure_window(wm.xcb_conn, client->window, mask, ¶ms);
|
||||
logger("== client 0x%x resize to width: %d, height: %d\n", client->window,
|
||||
width, height);
|
||||
}
|
||||
|
||||
bool client_is_visible(client_t *client) {
|
||||
return client->tags & client->monitor->selected_tag->mask;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
#include "types.h"
|
||||
|
||||
client_t *client_get_by_window(xcb_window_t window);
|
||||
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag);
|
||||
void client_manage(xcb_window_t window,
|
||||
xcb_get_geometry_reply_t *geometry_reply);
|
||||
bool client_need_layout(client_t *client);
|
||||
|
||||
void client_send_to_tag(client_t *client, uint32_t tag_mask);
|
||||
void client_send_to_monitor(client_t *client, monitor_t *monitor);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "action.h"
|
||||
#include "layout.h"
|
||||
#include "types.h"
|
||||
|
||||
static const char *const font_family = "monospace";
|
||||
@@ -35,6 +36,6 @@ static const keyboard_t key_list[] = {
|
||||
};
|
||||
|
||||
static const layout_t layout_list[] = {
|
||||
{.symbol = "[M]", .arrange = nullptr},
|
||||
{.symbol = "[M]", .arrange = monocle},
|
||||
{.symbol = "><=", .arrange = nullptr},
|
||||
};
|
||||
|
||||
19
src/layout.c
Normal file
19
src/layout.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "layout.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
|
||||
void monocle(tag_t *tag) {
|
||||
logger("== monocle tag: %s start ==\n", tag->name);
|
||||
for (task_in_tag_t *task = tag->task_list; task; task = task->next) {
|
||||
if (!client_need_layout(task->client)) continue;
|
||||
task->geometry = task->client->monitor->workarea;
|
||||
logger("== window 0x%x: x: %d, y: %d, width: %u, height: %u\n",
|
||||
task->client->window, task->geometry.x, task->geometry.y,
|
||||
task->geometry.width, task->geometry.height);
|
||||
}
|
||||
logger("== monocle tag: %s end ==\n", tag->name);
|
||||
}
|
||||
5
src/layout.h
Normal file
5
src/layout.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void monocle(tag_t *tag);
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xcb/xcb_aux.h>
|
||||
|
||||
#include "base.h"
|
||||
#include "client.h"
|
||||
#include "color.h"
|
||||
#include "text.h"
|
||||
#include "types.h"
|
||||
@@ -210,3 +211,29 @@ void monitor_draw_bar(monitor_t *monitor) {
|
||||
monitor_draw_tags(monitor);
|
||||
monitor_draw_layout_symbol(monitor);
|
||||
}
|
||||
|
||||
void monitor_arrange(monitor_t *monitor) {
|
||||
tag_t *tag = monitor->selected_tag;
|
||||
if (tag->layout && tag->layout->arrange) tag->layout->arrange(tag);
|
||||
|
||||
for (client_t *c = wm.client_list; c; c = c->next) {
|
||||
task_in_tag_t *task = client_get_task_in_tag(c, tag);
|
||||
if (task) {
|
||||
if (task->geometry.x != c->geometry.x ||
|
||||
task->geometry.y != c->geometry.y) {
|
||||
client_move_to(c, task->geometry.x, task->geometry.y);
|
||||
}
|
||||
if (task->geometry.width != c->geometry.width ||
|
||||
task->geometry.height != c->geometry.height) {
|
||||
client_resize(c, task->geometry.width, task->geometry.height);
|
||||
}
|
||||
} else {
|
||||
int16_t x = -c->geometry.width;
|
||||
int16_t y = -c->geometry.height;
|
||||
if (x != c->geometry.x || y != c->geometry.y) {
|
||||
client_move_to(c, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
xcb_flush(wm.xcb_conn);
|
||||
}
|
||||
|
||||
@@ -10,3 +10,4 @@ void monitor_select_tag(monitor_t *monitor, uint32_t tag_mask);
|
||||
void monitor_clean(monitor_t *monitor);
|
||||
void monitor_init_bar(monitor_t *monitor);
|
||||
void monitor_draw_bar(monitor_t *monitor);
|
||||
void monitor_arrange(monitor_t *monitor);
|
||||
|
||||
Reference in New Issue
Block a user