diff --git a/src/main.c b/src/main.c index f74f662..e4f451e 100644 --- a/src/main.c +++ b/src/main.c @@ -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)) {