mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-24 13:36:42 -04:00
feat(ipc): add 'get cursorpos' and 'get option <name>' queries
This commit is contained in:
parent
8e356692f6
commit
fa4f144b9d
5 changed files with 276 additions and 0 deletions
|
|
@ -24,6 +24,8 @@ description: Control mangowm programmatically using mmsg.
|
|||
| Command | Description |
|
||||
| :--- | :--- |
|
||||
| `get version` | Returns the current version of the compositor. |
|
||||
| `get cursorpos` | Returns the global pointer position (`x`, `y`) and the monitor under it. |
|
||||
| `get option <name>` | Returns the current value of a scalar config option. Numbers as numbers, colors as `0xRRGGBBAA` strings, bezier curves as 4-element arrays. |
|
||||
| `get keymode` | Returns the current active keyboard mode (e.g., normal, insert). |
|
||||
| `get keyboardlayout` | Returns the active XKB layout (abbreviated). |
|
||||
| `get monitor <name>` | Returns full JSON details for a specific monitor. |
|
||||
|
|
@ -41,6 +43,7 @@ description: Control mangowm programmatically using mmsg.
|
|||
mmsg get monitor eDP-1
|
||||
mmsg get all-clients
|
||||
mmsg get all-monitors
|
||||
mmsg get option bordercolor
|
||||
```
|
||||
|
||||
### WATCH (Event Subscription)
|
||||
|
|
|
|||
11
mmsg/mmsg.1
11
mmsg/mmsg.1
|
|
@ -21,6 +21,17 @@ All \fBget\fR commands print a single JSON object and then close the connection.
|
|||
\fBget version\fR
|
||||
Return compositor version.
|
||||
.TP
|
||||
\fBget cursorpos\fR
|
||||
Return the global pointer position (\fBx\fR, \fBy\fR) and the monitor under it
|
||||
(\fBnull\fR if over no output).
|
||||
.TP
|
||||
\fBget option \fIname\fR
|
||||
Return the current value of a scalar config option. Numbers are returned as
|
||||
numbers, colors as \fB0xRRGGBBAA\fR strings, bezier curves as 4-element arrays.
|
||||
Values round-trip through \fBdispatch setoption,\fIname\fB,\fIvalue\fR, except
|
||||
the comma-list options \fBcircle_layout\fR and \fBscroller_proportion_preset\fR
|
||||
(readable as arrays, but written via the config file).
|
||||
.TP
|
||||
\fBget keymode\fR
|
||||
Return current keymode.
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ static void usage(void) {
|
|||
printf("One-shot queries (get):\n");
|
||||
printf(
|
||||
" get version Show compositor version\n");
|
||||
printf(" get cursorpos Show pointer position + "
|
||||
"monitor\n");
|
||||
printf(" get option <name> Show current value of a "
|
||||
"config option\n");
|
||||
printf(" get keymode Show current keymode\n");
|
||||
printf(" get keyboardlayout Show current keyboard "
|
||||
"layout\n");
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#include <cjson/cJSON.h>
|
||||
#include <ctype.h>
|
||||
#include <libgen.h>
|
||||
#include <stdbool.h>
|
||||
|
|
@ -3016,6 +3017,244 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static cJSON *ipc_color_to_hex(const float c[4]) {
|
||||
unsigned r = (unsigned)(c[0] * 255.0f + 0.5f);
|
||||
unsigned g = (unsigned)(c[1] * 255.0f + 0.5f);
|
||||
unsigned b = (unsigned)(c[2] * 255.0f + 0.5f);
|
||||
unsigned a = (unsigned)(c[3] * 255.0f + 0.5f);
|
||||
char buf[11];
|
||||
snprintf(buf, sizeof(buf), "0x%02X%02X%02X%02X", r, g, b, a);
|
||||
return cJSON_CreateString(buf);
|
||||
}
|
||||
|
||||
static cJSON *ipc_curve_to_json(const double v[4]) {
|
||||
cJSON *arr = cJSON_CreateArray();
|
||||
for (int i = 0; i < 4; i++)
|
||||
cJSON_AddItemToArray(arr, cJSON_CreateNumber(v[i]));
|
||||
return arr;
|
||||
}
|
||||
|
||||
cJSON *read_option(Config *config, const char *key) {
|
||||
#define OPT_NUM(k, f) \
|
||||
if (strcmp(key, k) == 0) \
|
||||
return cJSON_CreateNumber(config->f)
|
||||
#define OPT_STR(k, f) \
|
||||
if (strcmp(key, k) == 0) \
|
||||
return cJSON_CreateString(config->f)
|
||||
#define OPT_STRP(k, f) \
|
||||
if (strcmp(key, k) == 0) \
|
||||
return config->f ? cJSON_CreateString(config->f) : cJSON_CreateNull()
|
||||
#define OPT_COLOR(k, f) \
|
||||
if (strcmp(key, k) == 0) \
|
||||
return ipc_color_to_hex(config->f)
|
||||
#define OPT_CURVE(k, f) \
|
||||
if (strcmp(key, k) == 0) \
|
||||
return ipc_curve_to_json(config->f)
|
||||
|
||||
OPT_STR("keymode", keymode);
|
||||
OPT_NUM("animations", animations);
|
||||
OPT_NUM("layer_animations", layer_animations);
|
||||
OPT_STR("animation_type_open", animation_type_open);
|
||||
OPT_STR("animation_type_close", animation_type_close);
|
||||
OPT_STR("layer_animation_type_open", layer_animation_type_open);
|
||||
OPT_STR("layer_animation_type_close", layer_animation_type_close);
|
||||
OPT_NUM("animation_fade_in", animation_fade_in);
|
||||
OPT_NUM("animation_fade_out", animation_fade_out);
|
||||
OPT_NUM("tag_animation_direction", tag_animation_direction);
|
||||
OPT_NUM("zoom_initial_ratio", zoom_initial_ratio);
|
||||
OPT_NUM("zoom_end_ratio", zoom_end_ratio);
|
||||
OPT_NUM("fadein_begin_opacity", fadein_begin_opacity);
|
||||
OPT_NUM("fadeout_begin_opacity", fadeout_begin_opacity);
|
||||
OPT_NUM("animation_duration_move", animation_duration_move);
|
||||
OPT_NUM("animation_duration_open", animation_duration_open);
|
||||
OPT_NUM("animation_duration_tag", animation_duration_tag);
|
||||
OPT_NUM("animation_duration_close", animation_duration_close);
|
||||
OPT_NUM("animation_duration_focus", animation_duration_focus);
|
||||
OPT_CURVE("animation_curve_move", animation_curve_move);
|
||||
OPT_CURVE("animation_curve_open", animation_curve_open);
|
||||
OPT_CURVE("animation_curve_tag", animation_curve_tag);
|
||||
OPT_CURVE("animation_curve_close", animation_curve_close);
|
||||
OPT_CURVE("animation_curve_focus", animation_curve_focus);
|
||||
OPT_CURVE("animation_curve_opafadein", animation_curve_opafadein);
|
||||
OPT_CURVE("animation_curve_opafadeout", animation_curve_opafadeout);
|
||||
OPT_NUM("scroller_structs", scroller_structs);
|
||||
OPT_NUM("scroller_default_proportion", scroller_default_proportion);
|
||||
OPT_NUM("scroller_default_proportion_single",
|
||||
scroller_default_proportion_single);
|
||||
OPT_NUM("scroller_ignore_proportion_single",
|
||||
scroller_ignore_proportion_single);
|
||||
OPT_NUM("scroller_focus_center", scroller_focus_center);
|
||||
OPT_NUM("scroller_prefer_center", scroller_prefer_center);
|
||||
OPT_NUM("scroller_prefer_overspread", scroller_prefer_overspread);
|
||||
OPT_NUM("edge_scroller_pointer_focus", edge_scroller_pointer_focus);
|
||||
OPT_NUM("edge_scroller_focus_allow_speed", edge_scroller_focus_allow_speed);
|
||||
OPT_NUM("focus_cross_monitor", focus_cross_monitor);
|
||||
OPT_NUM("exchange_cross_monitor", exchange_cross_monitor);
|
||||
OPT_NUM("scratchpad_cross_monitor", scratchpad_cross_monitor);
|
||||
OPT_NUM("focus_cross_tag", focus_cross_tag);
|
||||
OPT_NUM("view_current_to_back", view_current_to_back);
|
||||
OPT_NUM("blur", blur);
|
||||
OPT_NUM("blur_layer", blur_layer);
|
||||
OPT_NUM("blur_optimized", blur_optimized);
|
||||
OPT_NUM("border_radius", border_radius);
|
||||
OPT_NUM("blur_params_num_passes", blur_params.num_passes);
|
||||
OPT_NUM("blur_params_radius", blur_params.radius);
|
||||
OPT_NUM("blur_params_noise", blur_params.noise);
|
||||
OPT_NUM("blur_params_brightness", blur_params.brightness);
|
||||
OPT_NUM("blur_params_contrast", blur_params.contrast);
|
||||
OPT_NUM("blur_params_saturation", blur_params.saturation);
|
||||
OPT_NUM("shadows", shadows);
|
||||
OPT_NUM("shadow_only_floating", shadow_only_floating);
|
||||
OPT_NUM("layer_shadows", layer_shadows);
|
||||
OPT_NUM("shadows_size", shadows_size);
|
||||
OPT_NUM("shadows_blur", shadows_blur);
|
||||
OPT_NUM("shadows_position_x", shadows_position_x);
|
||||
OPT_NUM("shadows_position_y", shadows_position_y);
|
||||
OPT_NUM("single_scratchpad", single_scratchpad);
|
||||
OPT_NUM("xwayland_persistence", xwayland_persistence);
|
||||
OPT_NUM("syncobj_enable", syncobj_enable);
|
||||
OPT_NUM("tag_carousel", tag_carousel);
|
||||
OPT_NUM("drag_tile_refresh_interval", drag_tile_refresh_interval);
|
||||
OPT_NUM("drag_floating_refresh_interval", drag_floating_refresh_interval);
|
||||
OPT_NUM("allow_tearing", allow_tearing);
|
||||
OPT_NUM("allow_shortcuts_inhibit", allow_shortcuts_inhibit);
|
||||
OPT_NUM("allow_lock_transparent", allow_lock_transparent);
|
||||
OPT_NUM("no_border_when_single", no_border_when_single);
|
||||
OPT_NUM("no_radius_when_single", no_radius_when_single);
|
||||
OPT_NUM("snap_distance", snap_distance);
|
||||
OPT_NUM("enable_floating_snap", enable_floating_snap);
|
||||
OPT_NUM("drag_tile_to_tile", drag_tile_to_tile);
|
||||
OPT_NUM("drag_tile_small", drag_tile_small);
|
||||
OPT_NUM("swipe_min_threshold", swipe_min_threshold);
|
||||
OPT_NUM("focused_opacity", focused_opacity);
|
||||
OPT_NUM("unfocused_opacity", unfocused_opacity);
|
||||
OPT_STR("xkb_rules_rules", xkb_rules_rules);
|
||||
OPT_STR("xkb_rules_model", xkb_rules_model);
|
||||
OPT_STR("xkb_rules_layout", xkb_rules_layout);
|
||||
OPT_STR("xkb_rules_variant", xkb_rules_variant);
|
||||
OPT_STR("xkb_rules_options", xkb_rules_options);
|
||||
OPT_NUM("new_is_master", new_is_master);
|
||||
OPT_NUM("default_mfact", default_mfact);
|
||||
OPT_NUM("default_nmaster", default_nmaster);
|
||||
OPT_NUM("center_master_overspread", center_master_overspread);
|
||||
OPT_NUM("center_when_single_stack", center_when_single_stack);
|
||||
OPT_NUM("dwindle_vsplit", dwindle_vsplit);
|
||||
OPT_NUM("dwindle_hsplit", dwindle_hsplit);
|
||||
OPT_NUM("dwindle_preserve_split", dwindle_preserve_split);
|
||||
OPT_NUM("dwindle_smart_split", dwindle_smart_split);
|
||||
OPT_NUM("dwindle_smart_resize", dwindle_smart_resize);
|
||||
OPT_NUM("dwindle_drop_simple_split", dwindle_drop_simple_split);
|
||||
OPT_NUM("dwindle_manual_split", dwindle_manual_split);
|
||||
OPT_NUM("dwindle_split_ratio", dwindle_split_ratio);
|
||||
OPT_NUM("hotarea_size", hotarea_size);
|
||||
OPT_NUM("hotarea_corner", hotarea_corner);
|
||||
OPT_NUM("enable_hotarea", enable_hotarea);
|
||||
OPT_NUM("ov_tab_mode", ov_tab_mode);
|
||||
OPT_NUM("ov_no_resize", ov_no_resize);
|
||||
OPT_NUM("overviewgappi", overviewgappi);
|
||||
OPT_NUM("overviewgappo", overviewgappo);
|
||||
OPT_NUM("cursor_hide_timeout", cursor_hide_timeout);
|
||||
OPT_NUM("cursor_hide_on_keypress", cursor_hide_on_keypress);
|
||||
OPT_NUM("axis_bind_apply_timeout", axis_bind_apply_timeout);
|
||||
OPT_NUM("focus_on_activate", focus_on_activate);
|
||||
OPT_NUM("numlockon", numlockon);
|
||||
OPT_NUM("idleinhibit_ignore_visible", idleinhibit_ignore_visible);
|
||||
OPT_NUM("sloppyfocus", sloppyfocus);
|
||||
OPT_NUM("warpcursor", warpcursor);
|
||||
OPT_NUM("drag_corner", drag_corner);
|
||||
OPT_NUM("drag_warp_cursor", drag_warp_cursor);
|
||||
OPT_NUM("smartgaps", smartgaps);
|
||||
OPT_NUM("repeat_rate", repeat_rate);
|
||||
OPT_NUM("repeat_delay", repeat_delay);
|
||||
OPT_NUM("disable_trackpad", disable_trackpad);
|
||||
OPT_NUM("tap_to_click", tap_to_click);
|
||||
OPT_NUM("tap_and_drag", tap_and_drag);
|
||||
OPT_NUM("drag_lock", drag_lock);
|
||||
OPT_NUM("mouse_natural_scrolling", mouse_natural_scrolling);
|
||||
OPT_NUM("trackpad_natural_scrolling", trackpad_natural_scrolling);
|
||||
OPT_NUM("cursor_size", cursor_size);
|
||||
OPT_STRP("cursor_theme", cursor_theme);
|
||||
OPT_STRP("tab_bar_decorate_font_desc", tabdata.font_desc);
|
||||
OPT_COLOR("tab_bar_decorate_fg_color", tabdata.fg_color);
|
||||
OPT_COLOR("tab_bar_decorate_bg_color", tabdata.bg_color);
|
||||
OPT_COLOR("tab_bar_decorate_focus_fg_color", tabdata.focus_fg_color);
|
||||
OPT_COLOR("tab_bar_decorate_focus_bg_color", tabdata.focus_bg_color);
|
||||
OPT_COLOR("tab_bar_decorate_border_color", tabdata.border_color);
|
||||
OPT_NUM("tab_bar_decorate_border_width", tabdata.border_width);
|
||||
OPT_NUM("tab_bar_decorate_corner_radius", tabdata.corner_radius);
|
||||
OPT_NUM("tab_bar_decorate_padding_x", tabdata.padding_x);
|
||||
OPT_NUM("tab_bar_decorate_padding_y", tabdata.padding_y);
|
||||
OPT_STRP("jump_label_decorate_font_desc", jumplabeldata.font_desc);
|
||||
OPT_COLOR("jump_label_decorate_fg_color", jumplabeldata.fg_color);
|
||||
OPT_COLOR("jump_label_decorate_bg_color", jumplabeldata.bg_color);
|
||||
OPT_COLOR("jump_label_decorate_focus_fg_color",
|
||||
jumplabeldata.focus_fg_color);
|
||||
OPT_COLOR("jump_label_decorate_focus_bg_color",
|
||||
jumplabeldata.focus_bg_color);
|
||||
OPT_COLOR("jump_label_decorate_border_color", jumplabeldata.border_color);
|
||||
OPT_NUM("jump_label_decorate_border_width", jumplabeldata.border_width);
|
||||
OPT_NUM("jump_label_decorate_corner_radius", jumplabeldata.corner_radius);
|
||||
OPT_NUM("jump_label_decorate_padding_x", jumplabeldata.padding_x);
|
||||
OPT_NUM("jump_label_decorate_padding_y", jumplabeldata.padding_y);
|
||||
OPT_NUM("disable_while_typing", disable_while_typing);
|
||||
OPT_NUM("left_handed", left_handed);
|
||||
OPT_NUM("middle_button_emulation", middle_button_emulation);
|
||||
OPT_NUM("mouse_accel_profile", mouse_accel_profile);
|
||||
OPT_NUM("mouse_accel_speed", mouse_accel_speed);
|
||||
OPT_NUM("trackpad_accel_profile", trackpad_accel_profile);
|
||||
OPT_NUM("trackpad_accel_speed", trackpad_accel_speed);
|
||||
OPT_NUM("scroll_method", scroll_method);
|
||||
OPT_NUM("scroll_button", scroll_button);
|
||||
OPT_NUM("click_method", click_method);
|
||||
OPT_NUM("send_events_mode", send_events_mode);
|
||||
OPT_NUM("button_map", button_map);
|
||||
OPT_NUM("axis_scroll_factor", axis_scroll_factor);
|
||||
OPT_STRP("tablet_map_to_mon", tablet_map_to_mon);
|
||||
OPT_NUM("trackpad_scroll_factor", trackpad_scroll_factor);
|
||||
OPT_NUM("gappih", gappih);
|
||||
OPT_NUM("gappiv", gappiv);
|
||||
OPT_NUM("gappoh", gappoh);
|
||||
OPT_NUM("gappov", gappov);
|
||||
OPT_NUM("scratchpad_width_ratio", scratchpad_width_ratio);
|
||||
OPT_NUM("scratchpad_height_ratio", scratchpad_height_ratio);
|
||||
OPT_NUM("borderpx", borderpx);
|
||||
OPT_NUM("tab_bar_height", tab_bar_height);
|
||||
OPT_COLOR("rootcolor", rootcolor);
|
||||
OPT_COLOR("shadowscolor", shadowscolor);
|
||||
OPT_COLOR("bordercolor", bordercolor);
|
||||
OPT_COLOR("dropcolor", dropcolor);
|
||||
OPT_COLOR("splitcolor", splitcolor);
|
||||
OPT_COLOR("focuscolor", focuscolor);
|
||||
OPT_COLOR("maximizescreencolor", maximizescreencolor);
|
||||
OPT_COLOR("urgentcolor", urgentcolor);
|
||||
OPT_COLOR("scratchpadcolor", scratchpadcolor);
|
||||
OPT_COLOR("globalcolor", globalcolor);
|
||||
OPT_COLOR("overlaycolor", overlaycolor);
|
||||
|
||||
#undef OPT_NUM
|
||||
#undef OPT_STR
|
||||
#undef OPT_STRP
|
||||
#undef OPT_COLOR
|
||||
#undef OPT_CURVE
|
||||
|
||||
if (strcmp(key, "scroller_proportion_preset") == 0) {
|
||||
cJSON *arr = cJSON_CreateArray();
|
||||
for (int32_t i = 0; i < config->scroller_proportion_preset_count; i++)
|
||||
cJSON_AddItemToArray(
|
||||
arr, cJSON_CreateNumber(config->scroller_proportion_preset[i]));
|
||||
return arr;
|
||||
}
|
||||
if (strcmp(key, "circle_layout") == 0) {
|
||||
cJSON *arr = cJSON_CreateArray();
|
||||
for (int32_t i = 0; i < config->circle_layout_count; i++)
|
||||
cJSON_AddItemToArray(arr,
|
||||
cJSON_CreateString(config->circle_layout[i]));
|
||||
return arr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool parse_config_line(Config *config, const char *line) {
|
||||
char key[256], value[256];
|
||||
if (sscanf(line, "%255[^=]=%255[^\n]", key, value) != 2) {
|
||||
|
|
|
|||
|
|
@ -237,6 +237,15 @@ static void handle_command(int client_fd, const char *cmd_raw) {
|
|||
if (strcmp(cmd, "get version") == 0) {
|
||||
resp = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(resp, "version", VERSION);
|
||||
} else if (strcmp(cmd, "get cursorpos") == 0) {
|
||||
resp = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(resp, "x", cursor->x);
|
||||
cJSON_AddNumberToObject(resp, "y", cursor->y);
|
||||
Monitor *m = xytomon(cursor->x, cursor->y);
|
||||
if (m)
|
||||
cJSON_AddStringToObject(resp, "monitor", m->wlr_output->name);
|
||||
else
|
||||
cJSON_AddNullToObject(resp, "monitor");
|
||||
} else if (strcmp(cmd, "get keymode") == 0) {
|
||||
resp = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(resp, "keymode", keymode.mode);
|
||||
|
|
@ -342,6 +351,16 @@ static void handle_command(int client_fd, const char *cmd_raw) {
|
|||
return;
|
||||
}
|
||||
resp = build_monitor_tags_response(m);
|
||||
} else if (strncmp(cmd, "get option ", 11) == 0) {
|
||||
cJSON *val = read_option(&config, cmd + 11);
|
||||
if (!val) {
|
||||
send_static_json(client_fd,
|
||||
"{\"error\":\"unknown or unreadable option\"}\n");
|
||||
return;
|
||||
}
|
||||
resp = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(resp, "option", cmd + 11);
|
||||
cJSON_AddItemToObject(resp, "value", val);
|
||||
} else if (strncmp(cmd, "dispatch ", 9) == 0) {
|
||||
char *dispatch_copy = strdup(cmd_raw + 9);
|
||||
char *out = dispatch_copy, *ptr = dispatch_copy;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue