调整有多个 class 相同的 client 时 raise_or_run 的行为

This commit is contained in:
2025-08-30 20:39:33 +08:00
parent e347dabc21
commit 91c417a0e3

View File

@@ -73,6 +73,7 @@ static monitor_t *get_monitor_by_direction(bool forward);
static void send_client_to_monitor(client_t *client, monitor_t *monitor);
static void set_client_tag_prop(client_t *client);
static bool restore_client_tag(client_t *client);
static client_t *get_next_client_with_class(const char *class);
static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
gpointer userdata);
static void cleanup(bool will_restart);
@@ -170,25 +171,25 @@ void focus_monitor(const user_action_arg_t *arg) {
void raise_or_run(const user_action_arg_t *arg) {
const char *class = ((const char **)arg->ptr)[0];
const char *command = ((const char **)arg->ptr)[1];
client_t *client = get_next_client_with_class(class);
if (client && client == current_monitor->selected_client) return;
user_action_arg_t argument;
for (monitor_t *m = monitors; m; m = m->next) {
for (client_t *c = m->clients; c; c = c->next) {
window_class_instance_t class_instance;
get_window_class_instance(c->window, &class_instance);
if (!strncmp(class, class_instance.class, sizeof(class_instance.class))) {
current_monitor = m;
argument.ui = c->tags;
select_tag(&argument);
focus(c);
raise_window(c->window);
return;
}
}
if (client) {
logger("==== raise client: %s, window: 0x%x\n", client->name,
client->window);
current_monitor = client->monitor;
argument.ui = client->tags;
select_tag(&argument);
focus(client);
raise_window(client->window);
return;
}
const char *command = ((const char **)arg->ptr)[1];
argument.ptr = command;
spawn(&argument);
return;
}
void toggle_mute(const user_action_arg_t *arg) { toggle_pulse_mute(); }
@@ -1202,6 +1203,53 @@ bool restore_client_tag(client_t *client) {
return false;
}
client_t *get_next_client_with_class(const char *class) {
monitor_t *m = NULL;
client_t *c = NULL;
window_class_instance_t class_instance;
for (m = current_monitor; m; m = m->next) {
if (m == current_monitor && m->selected_client) {
c = m->selected_client->next;
} else {
c = m->clients;
}
for (; c; c = c->next) {
get_window_class_instance(c->window, &class_instance);
if (!strncmp(class, class_instance.class, sizeof(class_instance.class))) {
return c;
}
}
}
for (m = monitors; m && m != current_monitor; m = m->next) {
for (c = m->clients; c; c = c->next) {
get_window_class_instance(c->window, &class_instance);
if (!strncmp(class, class_instance.class, sizeof(class_instance.class))) {
return c;
}
}
}
m = current_monitor;
for (c = m->clients; c && m->selected_client && c != m->selected_client;
c = c->next) {
get_window_class_instance(c->window, &class_instance);
if (!strncmp(class, class_instance.class, sizeof(class_instance.class))) {
return c;
}
}
if (current_monitor->selected_client) {
get_window_class_instance(c->window, &class_instance);
if (!strncmp(class, class_instance.class, sizeof(class_instance.class))) {
return c;
}
}
return NULL;
}
gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
gpointer userdata) {
if (condition & (G_IO_HUP | G_IO_ERR)) {