添加 raise_or_run 功能

This commit is contained in:
2026-01-28 11:43:07 +08:00
parent 99d2e33a46
commit 5ecaa97f10
5 changed files with 61 additions and 3 deletions

View File

@@ -57,3 +57,21 @@ void quit(const user_action_arg_t *arg) {
wm_quit(); wm_quit();
} }
} }
void raise_or_run(const user_action_arg_t *arg) {
const char *class = ((const char **)arg->ptr)[0];
client_t *client = client_get_next_by_class(wm.client_focused, class);
if (client && client == wm.client_focused) return;
if (client) {
wm.current_monitor = client->monitor;
monitor_select_tag(client->monitor, client->tags);
client_stack_raise(client);
client_focus(client);
return;
}
const char *command = ((const char **)arg->ptr)[1];
user_action_arg_t arguments = {.ptr = command};
spawn(&arguments);
}

View File

@@ -54,3 +54,4 @@ void send_client_to_tag(const user_action_arg_t *arg);
void send_client_to_next_monitor(const user_action_arg_t *arg); void send_client_to_next_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);
void raise_or_run(const user_action_arg_t *arg);

View File

@@ -23,6 +23,19 @@ client_t *client_get_by_window(xcb_window_t window) {
return nullptr; return nullptr;
} }
client_t *client_get_next_by_class(client_t *current, const char *class) {
client_t *start = current ? current->next : wm.client_list;
for (client_t *c = start; c; c = c->next) {
if (strcmp(class, c->class) == 0) return c;
}
for (client_t *c = wm.client_list; c && c != start; c = c->next) {
if (strcmp(class, c->class) == 0) return c;
}
return nullptr;
}
static void client_attach_list(client_t *client) { static void client_attach_list(client_t *client) {
client->next = wm.client_list; client->next = wm.client_list;
wm.client_list = client; wm.client_list = client;

View File

@@ -6,6 +6,7 @@
#include "types.h" #include "types.h"
client_t *client_get_by_window(xcb_window_t window); client_t *client_get_by_window(xcb_window_t window);
client_t *client_get_next_by_class(client_t *current,const char *class);
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_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); task_in_tag_t *client_get_previous_task_in_tag(client_t *client, tag_t *tag);

View File

@@ -37,10 +37,35 @@ static const button_t button_list[] = {
static const char launcher[] = static const char launcher[] =
"rofi -show combi -modes combi -combi-modes window,drun,run,ssh,windowcd"; "rofi -show combi -modes combi -combi-modes window,drun,run,ssh,windowcd";
static const char terminal[] = "xterm";
static const char terminal_class[] = "XTerm";
static const char editor[] = "emacsclient -a '' -r";
static const char editor_class[] = "Emacs";
static const char browser[] = "firefox-bin";
static const char browser_class[] = "firefox";
static const keyboard_t key_list[] = { static const keyboard_t key_list[] = {
{modifier_super, XK_p, spawn, {.ptr = launcher}}, {modifier_super, XK_r, spawn, {.ptr = launcher}},
{modifier_super, XK_q, quit, {.b = false}}, {modifier_super, XK_Return, spawn, {.ptr = terminal}},
{modifier_super, XK_r, quit, {.b = true}}, {
modifier_control | modifier_alt,
XK_r,
raise_or_run,
{.ptr = (const char *[]){terminal_class, terminal}},
},
{
modifier_super,
XK_e,
raise_or_run,
{.ptr = (const char *[]){editor_class, editor}},
},
{
modifier_super,
XK_q,
raise_or_run,
{.ptr = (const char *[]){browser_class, browser}},
},
{modifier_super | modifier_shift, XK_q, quit, {.b = false}},
{modifier_super | modifier_control, XK_r, quit, {.b = true}},
{modifier_super | modifier_shift, {modifier_super | modifier_shift,
XK_j, XK_j,
focus_client_in_same_tag, focus_client_in_same_tag,