处理堆叠顺序
This commit is contained in:
19
src/action.c
19
src/action.c
@@ -3,9 +3,28 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
|
#include "types.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
|
|
||||||
|
void focus_client_in_same_tag(const user_action_arg_t *arg) {
|
||||||
|
bool next = arg->b;
|
||||||
|
tag_t *tag = wm.current_monitor->selected_tag;
|
||||||
|
|
||||||
|
task_in_tag_t *task = nullptr;
|
||||||
|
if (next) {
|
||||||
|
task = client_get_next_task_in_tag(wm.client_focused, tag);
|
||||||
|
} else {
|
||||||
|
task = client_get_previous_task_in_tag(wm.client_focused, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!task) return;
|
||||||
|
|
||||||
|
client_stack_raise(task->client);
|
||||||
|
client_focus(task->client);
|
||||||
|
}
|
||||||
|
|
||||||
void select_tag_of_current_monitor(const user_action_arg_t *arg) {
|
void select_tag_of_current_monitor(const user_action_arg_t *arg) {
|
||||||
monitor_select_tag(wm.current_monitor, arg->ui);
|
monitor_select_tag(wm.current_monitor, arg->ui);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ typedef struct keyboard_t {
|
|||||||
const user_action_arg_t arg;
|
const user_action_arg_t arg;
|
||||||
} keyboard_t;
|
} keyboard_t;
|
||||||
|
|
||||||
|
void focus_client_in_same_tag(const user_action_arg_t *arg);
|
||||||
void select_tag_of_current_monitor(const user_action_arg_t *arg);
|
void select_tag_of_current_monitor(const user_action_arg_t *arg);
|
||||||
void spawn(const user_action_arg_t *arg);
|
void spawn(const user_action_arg_t *arg);
|
||||||
void quit(const user_action_arg_t *arg);
|
void quit(const user_action_arg_t *arg);
|
||||||
|
|||||||
24
src/client.c
24
src/client.c
@@ -58,6 +58,22 @@ task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task_in_tag_t *client_get_next_task_in_tag(client_t *client, tag_t *tag) {
|
||||||
|
if (!tag->task_list) return nullptr;
|
||||||
|
|
||||||
|
task_in_tag_t *task = tag->task_list;
|
||||||
|
for (; task && task->client != client; task = task->next);
|
||||||
|
return task && task->next ? task->next : tag->task_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag) {
|
||||||
|
if (!tag->task_list) return nullptr;
|
||||||
|
|
||||||
|
task_in_tag_t *task = tag->task_list;
|
||||||
|
for (; task && task->next && task->next->client != client; task = task->next);
|
||||||
|
return task ? task : tag->task_list;
|
||||||
|
}
|
||||||
|
|
||||||
static void client_add_to_tag(client_t *client, tag_t *tag) {
|
static void client_add_to_tag(client_t *client, tag_t *tag) {
|
||||||
if (client_get_task_in_tag(client, tag)) return;
|
if (client_get_task_in_tag(client, tag)) return;
|
||||||
|
|
||||||
@@ -191,6 +207,7 @@ void client_manage(xcb_window_t window,
|
|||||||
monitor_arrange(c->monitor);
|
monitor_arrange(c->monitor);
|
||||||
monitor_draw_bar(c->monitor);
|
monitor_draw_bar(c->monitor);
|
||||||
|
|
||||||
|
wm_restack_clients();
|
||||||
if (c->tags & c->monitor->selected_tag->mask) client_focus(c);
|
if (c->tags & c->monitor->selected_tag->mask) client_focus(c);
|
||||||
|
|
||||||
xcb_flush(wm.xcb_conn);
|
xcb_flush(wm.xcb_conn);
|
||||||
@@ -279,6 +296,7 @@ void client_unmanage(client_t *client) {
|
|||||||
|
|
||||||
client_wipe(client);
|
client_wipe(client);
|
||||||
|
|
||||||
|
wm_restack_clients();
|
||||||
monitor_deal_focus(m);
|
monitor_deal_focus(m);
|
||||||
monitor_arrange(m);
|
monitor_arrange(m);
|
||||||
monitor_draw_bar(m);
|
monitor_draw_bar(m);
|
||||||
@@ -303,6 +321,12 @@ void client_focus(client_t *client) {
|
|||||||
xwindow_focus(client ? client->window : XCB_WINDOW_NONE);
|
xwindow_focus(client ? client->window : XCB_WINDOW_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void client_stack_raise(client_t *client) {
|
||||||
|
client_detach_stack(client);
|
||||||
|
client_attach_stack(client);
|
||||||
|
wm_restack_clients();
|
||||||
|
}
|
||||||
|
|
||||||
bool client_is_visible(client_t *client) {
|
bool client_is_visible(client_t *client) {
|
||||||
return client->tags & client->monitor->selected_tag->mask;
|
return client->tags & client->monitor->selected_tag->mask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
client_t *client_get_by_window(xcb_window_t window);
|
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);
|
task_in_tag_t *client_get_task_in_tag(client_t *client, tag_t *tag);
|
||||||
|
task_in_tag_t *client_get_next_task_in_tag(client_t *client, tag_t *tag);
|
||||||
|
task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag);
|
||||||
void client_manage(xcb_window_t window,
|
void client_manage(xcb_window_t window,
|
||||||
xcb_get_geometry_reply_t *geometry_reply);
|
xcb_get_geometry_reply_t *geometry_reply);
|
||||||
char **client_get_task_title(client_t *client);
|
char **client_get_task_title(client_t *client);
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ static const keyboard_t key_list[] = {
|
|||||||
{modifier_alt, XK_p, spawn, {.ptr = launcher}},
|
{modifier_alt, XK_p, spawn, {.ptr = launcher}},
|
||||||
{modifier_alt, XK_q, quit, {.b = false}},
|
{modifier_alt, XK_q, quit, {.b = false}},
|
||||||
{modifier_alt, XK_r, quit, {.b = true}},
|
{modifier_alt, XK_r, quit, {.b = true}},
|
||||||
|
{modifier_alt | modifier_shift, XK_j, focus_client_in_same_tag, {.b = true}},
|
||||||
|
{modifier_alt | modifier_shift, XK_k, focus_client_in_same_tag, {.b = false}},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const layout_t layout_list[] = {
|
static const layout_t layout_list[] = {
|
||||||
|
|||||||
19
src/wm.c
19
src/wm.c
@@ -390,6 +390,25 @@ void wm_quit(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wm_restack_clients(void) {
|
||||||
|
xcb_window_t sibling_window = XCB_WINDOW_NONE;
|
||||||
|
for (client_t *c = wm.client_stack_list; c; c = c->stack_next) {
|
||||||
|
uint16_t mask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||||
|
xcb_params_configure_window_t params = {};
|
||||||
|
if (sibling_window == XCB_WINDOW_NONE) {
|
||||||
|
mask = XCB_CONFIG_WINDOW_STACK_MODE;
|
||||||
|
params.stack_mode = XCB_STACK_MODE_ABOVE;
|
||||||
|
} else {
|
||||||
|
mask = XCB_CONFIG_WINDOW_STACK_MODE | XCB_CONFIG_WINDOW_SIBLING;
|
||||||
|
params.stack_mode = XCB_STACK_MODE_BELOW;
|
||||||
|
params.sibling = sibling_window;
|
||||||
|
}
|
||||||
|
sibling_window = c->window;
|
||||||
|
xcb_aux_configure_window(wm.xcb_conn, c->window, mask, ¶ms);
|
||||||
|
}
|
||||||
|
xcb_flush(wm.xcb_conn);
|
||||||
|
}
|
||||||
|
|
||||||
static void debug_show_monitor_list(void) {
|
static void debug_show_monitor_list(void) {
|
||||||
logger("\n========================== monitors ==========================\n");
|
logger("\n========================== monitors ==========================\n");
|
||||||
for (monitor_t *m = wm.monitor_list; m; m = m->next) {
|
for (monitor_t *m = wm.monitor_list; m; m = m->next) {
|
||||||
|
|||||||
Reference in New Issue
Block a user