mirror of
https://github.com/hyprwm/hyprland-plugins.git
synced 2026-05-07 11:18:01 +02:00
add kbselecti and update README
This commit is contained in:
parent
faa6b41a73
commit
46ca043fbe
3 changed files with 150 additions and 34 deletions
|
|
@ -14,7 +14,7 @@ plugin {
|
|||
bg_col = rgb(111111)
|
||||
workspace_method = center current # [center/first] [workspace] e.g. first 1 or center m+1
|
||||
|
||||
gesture_distance = 300 # how far is the "max" for the gesture
|
||||
gesture_distance = 200 # how far is the "max" for the gesture
|
||||
gaps_out = 0 # outer margin (px)
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,8 @@ plugin {
|
|||
# numbers (labels)
|
||||
label_enable = 1
|
||||
label_font_size = 16
|
||||
# content mode: token (default) | id | index
|
||||
label_text_mode = token
|
||||
# positioning
|
||||
label_position = top-left # top-left|top-right|bottom-left|bottom-right|center
|
||||
label_offset_x = 6
|
||||
|
|
@ -54,10 +56,20 @@ plugin {
|
|||
label_scale_hover = 1.0
|
||||
label_scale_focus = 1.0
|
||||
# label background bubble
|
||||
label_bg_enable = 0
|
||||
label_bg_enable = 1
|
||||
label_bg_color = rgba(00000088)
|
||||
label_bg_rounding = 4
|
||||
label_bg_shape = circle # circle|square|rounded
|
||||
label_bg_rounding = 8 # used for rounded
|
||||
label_padding = 4
|
||||
# font + precision
|
||||
label_font_family = Sans
|
||||
label_font_bold = 0
|
||||
label_font_italic = 0
|
||||
label_text_underline = 0
|
||||
label_text_strikethrough = 0
|
||||
label_pixel_snap = 1
|
||||
# optional: override tokens (up to 50, comma-separated). Empty entries allowed.
|
||||
# label_token_map = "1,2,3,4,5,6,7,8,9,0,!,@,#,$,%,^,&,*,(,),a,b,c,..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -69,10 +81,10 @@ plugin {
|
|||
| columns | number | how many desktops are displayed on one line | `3` |
|
||||
| gaps_in | number | inner gaps between tiles | `5` |
|
||||
| gaps_out | number | outer margin around the grid | `0` |
|
||||
| bg_col | color | color in gaps (between desktops) | `rgb(000000)` |
|
||||
| bg_col | color | color in gaps (between desktops) | `rgb(111111)` |
|
||||
| workspace_method | [center/first] [workspace] | position of the desktops | `center current` |
|
||||
| skip_empty | boolean | whether the grid displays workspaces sequentially by id using selector "r" (`false`) or skips empty workspaces using selector "m" (`true`) | `false` |
|
||||
| gesture_distance | number | how far is the max for the gesture | `300` |
|
||||
| gesture_distance | number | how far is the max for the gesture | `200` |
|
||||
|
||||
#### Subcategory `scrolling`
|
||||
|
||||
|
|
@ -94,29 +106,70 @@ Applies to the scrolling layout overview
|
|||
bind = MODIFIER, KEY, hyprexpo:expo, OPTION
|
||||
```
|
||||
|
||||
Example:
|
||||
Example:
|
||||
```bash
|
||||
# This will toggle HyprExpo when SUPER+g is pressed
|
||||
bind = SUPER, g, hyprexpo:expo, toggle
|
||||
|
||||
# Optional submap for keyboard selection when Hyprexpo is active
|
||||
# Optional submap for keyboard selection when Hyprexpo is active (index-based, 1..46)
|
||||
submap = hyprexpo
|
||||
binde = , left, hyprexpo:kb_focus, left
|
||||
binde = , right, hyprexpo:kb_focus, right
|
||||
binde = , up, hyprexpo:kb_focus, up
|
||||
binde = , down, hyprexpo:kb_focus, down
|
||||
binde = , return, hyprexpo:kb_confirm
|
||||
# number selection by workspace id
|
||||
binde = , 1, hyprexpo:kb_selectn, 1
|
||||
binde = , 2, hyprexpo:kb_selectn, 2
|
||||
binde = , 3, hyprexpo:kb_selectn, 3
|
||||
binde = , 4, hyprexpo:kb_selectn, 4
|
||||
binde = , 5, hyprexpo:kb_selectn, 5
|
||||
binde = , 6, hyprexpo:kb_selectn, 6
|
||||
binde = , 7, hyprexpo:kb_selectn, 7
|
||||
binde = , 8, hyprexpo:kb_selectn, 8
|
||||
binde = , 9, hyprexpo:kb_selectn, 9
|
||||
binde = , 0, hyprexpo:kb_selectn, 0 # 0 -> 10
|
||||
bind = , left, hyprexpo:kb_focus, left
|
||||
bind = , right, hyprexpo:kb_focus, right
|
||||
bind = , up, hyprexpo:kb_focus, up
|
||||
bind = , down, hyprexpo:kb_focus, down
|
||||
bind = , return, hyprexpo:kb_confirm
|
||||
|
||||
# 1..10 via digits (0 -> 10)
|
||||
bind = , 1, hyprexpo:kb_selecti, 1
|
||||
bind = , 2, hyprexpo:kb_selecti, 2
|
||||
bind = , 3, hyprexpo:kb_selecti, 3
|
||||
bind = , 4, hyprexpo:kb_selecti, 4
|
||||
bind = , 5, hyprexpo:kb_selecti, 5
|
||||
bind = , 6, hyprexpo:kb_selecti, 6
|
||||
bind = , 7, hyprexpo:kb_selecti, 7
|
||||
bind = , 8, hyprexpo:kb_selecti, 8
|
||||
bind = , 9, hyprexpo:kb_selecti, 9
|
||||
bind = , 0, hyprexpo:kb_selecti, 10
|
||||
|
||||
# 11..20 via SHIFT+digits
|
||||
bind = SHIFT, 1, hyprexpo:kb_selecti, 11
|
||||
bind = SHIFT, 2, hyprexpo:kb_selecti, 12
|
||||
bind = SHIFT, 3, hyprexpo:kb_selecti, 13
|
||||
bind = SHIFT, 4, hyprexpo:kb_selecti, 14
|
||||
bind = SHIFT, 5, hyprexpo:kb_selecti, 15
|
||||
bind = SHIFT, 6, hyprexpo:kb_selecti, 16
|
||||
bind = SHIFT, 7, hyprexpo:kb_selecti, 17
|
||||
bind = SHIFT, 8, hyprexpo:kb_selecti, 18
|
||||
bind = SHIFT, 9, hyprexpo:kb_selecti, 19
|
||||
bind = SHIFT, 0, hyprexpo:kb_selecti, 20
|
||||
|
||||
# 21..46 via alpha
|
||||
bind = , a, hyprexpo:kb_selecti, 21
|
||||
bind = , b, hyprexpo:kb_selecti, 22
|
||||
bind = , c, hyprexpo:kb_selecti, 23
|
||||
bind = , d, hyprexpo:kb_selecti, 24
|
||||
bind = , e, hyprexpo:kb_selecti, 25
|
||||
bind = , f, hyprexpo:kb_selecti, 26
|
||||
bind = , g, hyprexpo:kb_selecti, 27
|
||||
bind = , h, hyprexpo:kb_selecti, 28
|
||||
bind = , i, hyprexpo:kb_selecti, 29
|
||||
bind = , j, hyprexpo:kb_selecti, 30
|
||||
bind = , k, hyprexpo:kb_selecti, 31
|
||||
bind = , l, hyprexpo:kb_selecti, 32
|
||||
bind = , m, hyprexpo:kb_selecti, 33
|
||||
bind = , n, hyprexpo:kb_selecti, 34
|
||||
bind = , o, hyprexpo:kb_selecti, 35
|
||||
bind = , p, hyprexpo:kb_selecti, 36
|
||||
bind = , q, hyprexpo:kb_selecti, 37
|
||||
bind = , r, hyprexpo:kb_selecti, 38
|
||||
bind = , s, hyprexpo:kb_selecti, 39
|
||||
bind = , t, hyprexpo:kb_selecti, 40
|
||||
bind = , u, hyprexpo:kb_selecti, 41
|
||||
bind = , v, hyprexpo:kb_selecti, 42
|
||||
bind = , w, hyprexpo:kb_selecti, 43
|
||||
bind = , x, hyprexpo:kb_selecti, 44
|
||||
bind = , y, hyprexpo:kb_selecti, 45
|
||||
bind = , z, hyprexpo:kb_selecti, 46
|
||||
submap = reset
|
||||
```
|
||||
|
||||
|
|
@ -135,7 +188,9 @@ Keyboard navigation dispatchers (when overview is active):
|
|||
- Wrapping can be configured with `keynav_wrap_h` and `keynav_wrap_v`.
|
||||
- Reading order (row-major) for horizontal movement can be enabled with `keynav_reading_order`. At grid ends it will wrap to start/end only if both `keynav_wrap_h` and `keynav_wrap_v` are enabled.
|
||||
- `hyprexpo:kb_confirm`: selects the focused tile.
|
||||
- `hyprexpo:kb_selectn, <digit>`: selects the workspace with that id if visible in the grid (0 → 10).
|
||||
- `hyprexpo:kb_selectn, <id>`: selects by workspace id (legacy; `0` → `10`).
|
||||
- `hyprexpo:kb_selecti, <index>`: selects by 1-based visual index (recommended for single-keystroke mapping).
|
||||
- `hyprexpo:kb_select, <token>`: selects by a single token (1..9, 0, a..z), mainly for symbol-based configs.
|
||||
|
||||
Border styles:
|
||||
- `simple`: single-color border using `border_width`, `border_color_current`, `border_color_focus`.
|
||||
|
|
@ -145,8 +200,8 @@ Border styles:
|
|||
- `plugin:hyprexpo:border_grad_focus = rgba(ffdd44ee) rgba(22aaffee) 30deg`
|
||||
|
||||
Gaps:
|
||||
- `gaps_in` controls the spacing between tiles.
|
||||
- `gaps_out` adds the same spacing around the outer edge of the grid.
|
||||
- `gaps_in` controls the inner spacing between tiles.
|
||||
- `gaps_out` adds an outer margin (px) around the grid (animated during open/close).
|
||||
|
||||
Labels (numbers):
|
||||
- `label_position`, `label_offset_x`, `label_offset_y` control placement per tile.
|
||||
|
|
@ -154,3 +209,12 @@ Labels (numbers):
|
|||
- Per-state colors: `label_color_default|hover|focus|current`.
|
||||
- Per-state scale multipliers: `label_scale_hover|focus`.
|
||||
- Optional background bubble behind text: `label_bg_*`, `label_padding`.
|
||||
- Content:
|
||||
- `label_text_mode = token` (default) uses the token sequence (1..9,0,!,@,#,…,a..z) or `label_token_map` if provided.
|
||||
- `label_text_mode = index` shows the 1-based visual index.
|
||||
- `label_text_mode = id` shows the workspace ID.
|
||||
- Token overrides:
|
||||
- `label_token_map` accepts up to 50 comma-separated entries to override tokens. Empty entries allowed (skip rendering).
|
||||
- Font & precision:
|
||||
- `label_font_family`, `label_font_bold`, `label_font_italic`, `label_text_underline`, `label_text_strikethrough`
|
||||
- `label_pixel_snap` (default 1) rounds positions to integer pixels for crisper text.
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ static SDispatchResult onKbFocusDispatcher(std::string arg);
|
|||
static SDispatchResult onKbConfirmDispatcher(std::string arg);
|
||||
static SDispatchResult onKbSelectNumberDispatcher(std::string arg);
|
||||
static SDispatchResult onKbSelectTokenDispatcher(std::string arg);
|
||||
static SDispatchResult onKbSelectIndexDispatcher(std::string arg);
|
||||
|
||||
//
|
||||
static void hkRenderWorkspace(void* thisptr, PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) {
|
||||
|
|
@ -254,6 +255,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
|||
HyprlandAPI::addDispatcherV2(PHANDLE, "hyprexpo:kb_confirm", ::onKbConfirmDispatcher);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "hyprexpo:kb_selectn", ::onKbSelectNumberDispatcher);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "hyprexpo:kb_select", ::onKbSelectTokenDispatcher);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "hyprexpo:kb_selecti", ::onKbSelectIndexDispatcher);
|
||||
|
||||
HyprlandAPI::addConfigKeyword(PHANDLE, "hyprexpo-gesture", ::expoGestureKeyword, {});
|
||||
|
||||
|
|
@ -276,7 +278,11 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
|||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_enable", Hyprlang::INT{1});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_color", Hyprlang::INT{0xFFFFFFFF});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_font_size", Hyprlang::INT{16});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_text_mode", Hyprlang::STRING{"id"});
|
||||
// label_text_mode: token (default) | id | index
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_text_mode", Hyprlang::STRING{"token"});
|
||||
// Optional override map for up to 50 tokens, comma-separated. Empty entries allowed.
|
||||
// Example: "1,2,3,4,5,6,7,8,9,0,!,@,#,$,%,^,&,*,(,),a,..."
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_token_map", Hyprlang::STRING{""});
|
||||
// defaults: center/middle within the label container
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_position", Hyprlang::STRING{"center"});
|
||||
HyprlandAPI::addConfigValue(PHANDLE, "plugin:hyprexpo:label_offset_x", Hyprlang::INT{0});
|
||||
|
|
@ -399,3 +405,18 @@ static SDispatchResult onKbSelectTokenDispatcher(std::string arg) {
|
|||
g_pOverview->onKbSelectToken(*idx);
|
||||
return {};
|
||||
}
|
||||
|
||||
static SDispatchResult onKbSelectIndexDispatcher(std::string arg) {
|
||||
if (!g_pOverview)
|
||||
return {};
|
||||
// trim
|
||||
while (!arg.empty() && std::isspace(arg.front())) arg.erase(arg.begin());
|
||||
while (!arg.empty() && std::isspace(arg.back())) arg.pop_back();
|
||||
int idx = -1;
|
||||
try { idx = std::stoi(arg); } catch (...) { idx = -1; }
|
||||
if (idx <= 0)
|
||||
return {.success = false, .error = "invalid index (expected >= 1)"};
|
||||
// convert to 0-based visible index
|
||||
g_pOverview->onKbSelectToken(idx - 1);
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -840,6 +840,7 @@ void COverview::fullRender() {
|
|||
static auto* const* PLABELSIZE = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_font_size")->getDataStaticPtr();
|
||||
static auto const* PLABELPOS = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_position")->getDataStaticPtr();
|
||||
static auto const* PLABELMODE = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_text_mode")->getDataStaticPtr();
|
||||
static auto const* PTOKENMAP = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_token_map")->getDataStaticPtr();
|
||||
static auto* const* PLABELOX = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_offset_x")->getDataStaticPtr();
|
||||
static auto* const* PLABELOY = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_offset_y")->getDataStaticPtr();
|
||||
static auto const* PLABELSHOW = (Hyprlang::STRING const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:hyprexpo:label_show")->getDataStaticPtr();
|
||||
|
|
@ -933,11 +934,41 @@ void COverview::fullRender() {
|
|||
tile.round();
|
||||
|
||||
std::string label;
|
||||
if (std::string{*PLABELMODE} == "token") {
|
||||
int k = tokenCounter;
|
||||
if (k <= 8) label = std::to_string(k + 1);
|
||||
else if (k == 9) label = "0";
|
||||
else label = std::string(1, char('a' + (k - 10)));
|
||||
const std::string mode{*PLABELMODE};
|
||||
if (mode == "token") {
|
||||
// override map (comma-separated) up to 50
|
||||
std::vector<std::string> tokens;
|
||||
if (!std::string{*PTOKENMAP}.empty()) {
|
||||
const std::string mapStr{*PTOKENMAP};
|
||||
size_t start = 0;
|
||||
for (size_t cur = 0; cur <= mapStr.size(); ++cur) {
|
||||
if (cur == mapStr.size() || mapStr[cur] == ',') {
|
||||
std::string t = mapStr.substr(start, cur - start);
|
||||
while (!t.empty() && std::isspace((unsigned char)t.front())) t.erase(t.begin());
|
||||
while (!t.empty() && std::isspace((unsigned char)t.back())) t.pop_back();
|
||||
tokens.push_back(t);
|
||||
start = cur + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int k = tokenCounter; // 0-based visible index
|
||||
if (k < (int)tokens.size() && !tokens[k].empty())
|
||||
label = tokens[k];
|
||||
else {
|
||||
if (k <= 8) label = std::to_string(k + 1); // 1..9
|
||||
else if (k == 9) label = "0"; // 10 -> 0
|
||||
else if (k >= 10 && k <= 19) { // 11..20
|
||||
static const char* SYM[10] = {"!","@","#","$","%","^","&","*","(",")"};
|
||||
label = SYM[k - 10];
|
||||
} else if (k >= 20 && k <= 45) {
|
||||
label = std::string(1, char('a' + (k - 20))); // 21..46 -> a..z
|
||||
} else {
|
||||
label = ""; // 47..50 blank by default
|
||||
}
|
||||
}
|
||||
} else if (mode == "index") {
|
||||
label = std::to_string(tokenCounter + 1);
|
||||
} else {
|
||||
label = std::to_string(images[id].workspaceID);
|
||||
}
|
||||
|
|
@ -955,8 +986,8 @@ void COverview::fullRender() {
|
|||
}
|
||||
};
|
||||
|
||||
// if label isn't shown per mode, still advance token index
|
||||
if (!shouldShow(id)) { tokenCounter++; continue; }
|
||||
// if label isn't shown per mode or label is empty, still advance token index
|
||||
if (!shouldShow(id) || label.empty()) { tokenCounter++; continue; }
|
||||
|
||||
CHyprColor col = CHyprColor{(uint64_t)**PLCOLDEF};
|
||||
float scl = 1.0f;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue