159 lines
4.4 KiB
C
159 lines
4.4 KiB
C
#include "action.h"
|
|
|
|
#include <glib.h>
|
|
#include <string.h>
|
|
|
|
#include "audio.h"
|
|
#include "client.h"
|
|
#include "monitor.h"
|
|
#include "types.h"
|
|
#include "wm.h"
|
|
#include "xcursor.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) {
|
|
monitor_select_tag(wm.current_monitor, arg->ui);
|
|
}
|
|
|
|
void send_client_to_tag(const user_action_arg_t *arg) {
|
|
if (wm.client_focused) client_send_to_tag(wm.client_focused, arg->ui);
|
|
}
|
|
|
|
void send_client_to_next_monitor(const user_action_arg_t *arg) {
|
|
if (!wm.client_focused) return;
|
|
|
|
monitor_t *next_monitor = wm_get_next_monitor(wm.client_focused->monitor);
|
|
if (wm.client_focused->monitor == next_monitor) return;
|
|
|
|
client_send_to_monitor(wm.client_focused, next_monitor);
|
|
}
|
|
|
|
void focus_next_monitor(const user_action_arg_t *arg) {
|
|
monitor_t *next_monitor = wm_get_next_monitor(wm.current_monitor);
|
|
if (next_monitor == wm.current_monitor) return;
|
|
|
|
wm_set_current_monitor(next_monitor, true);
|
|
if (wm.current_monitor->selected_tag->task_list) {
|
|
monitor_deal_focus(wm.current_monitor);
|
|
}
|
|
}
|
|
|
|
void spawn(const user_action_arg_t *arg) {
|
|
const char *cmd = (const char *)arg->ptr;
|
|
if (cmd == nullptr || strlen(cmd) == 0) return;
|
|
|
|
g_spawn_command_line_async((const char *)arg->ptr, nullptr);
|
|
}
|
|
|
|
void quit(const user_action_arg_t *arg) {
|
|
const bool restart = arg->b;
|
|
if (restart) {
|
|
wm_restart();
|
|
} else {
|
|
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) {
|
|
bool monitor_changed = client->monitor != wm.current_monitor;
|
|
bool tag_changed = client->tags != client->monitor->selected_tag->mask;
|
|
if (monitor_changed || tag_changed) {
|
|
point_t point = monitor_changed ? monitor_get_restore_cursor_point(
|
|
client->monitor)
|
|
: xcursor_query_pointer_position();
|
|
wm_ignore_enter_notify_at_point(point);
|
|
}
|
|
wm_set_current_monitor(client->monitor, true);
|
|
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);
|
|
}
|
|
|
|
void toggle_mute(const user_action_arg_t *arg) {
|
|
if (wm.status->pulse_context) toggle_pulse_mute(wm.status->pulse_context);
|
|
}
|
|
|
|
void change_volume(const user_action_arg_t *arg) {
|
|
if (wm.status->pulse_context) {
|
|
change_pulse_volume(wm.status->pulse_context, arg->i);
|
|
}
|
|
}
|
|
|
|
void toggle_client_floating(const user_action_arg_t *arg) {
|
|
if (!wm.client_focused) return;
|
|
|
|
client_set_floating(wm.client_focused, !wm.client_focused->floating);
|
|
}
|
|
|
|
void toggle_client_fullscreen(const user_action_arg_t *arg) {
|
|
if (!wm.client_focused) return;
|
|
|
|
client_set_fullscreen(wm.client_focused, !wm.client_focused->fullscreen);
|
|
}
|
|
|
|
void toggle_client_maximize(const user_action_arg_t *arg) {
|
|
if (!wm.client_focused) return;
|
|
|
|
client_set_maximize(wm.client_focused, !wm.client_focused->maximize);
|
|
}
|
|
|
|
void toggle_client_minimize(const user_action_arg_t *arg) {
|
|
client_t *client = wm.client_focused;
|
|
if (arg->ptr) client = (client_t *)arg->ptr;
|
|
if (!client) return;
|
|
|
|
client_set_minimize(client, !client->minimize);
|
|
}
|
|
|
|
void kill_client(const user_action_arg_t *arg) {
|
|
if (wm.client_focused) {
|
|
client_kill(wm.client_focused);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief 根据 client 的当前状态切换 client 下一状态
|
|
* @description 如果当前 client 被遮挡了或者最小化了,则显示出来,否则最小化
|
|
*/
|
|
void change_client_state_dwim(const user_action_arg_t *arg) {
|
|
client_t *client = (client_t *)arg->ptr;
|
|
if (!client) return;
|
|
|
|
if (client != wm.client_stack_list &&
|
|
client_get_obscured_state(client, wm.client_stack_list) !=
|
|
obscured_none) {
|
|
client_stack_raise(client);
|
|
client_focus(client);
|
|
return;
|
|
}
|
|
|
|
client_set_minimize(client, !client->minimize);
|
|
if (!client->minimize) client_stack_raise(client);
|
|
}
|