Skip to content

Commit

Permalink
hyprctl: add next and all to switchxkblayout
Browse files Browse the repository at this point in the history
fixes #7555
  • Loading branch information
vaxerski committed Aug 28, 2024
1 parent 00ee1cf commit d105c74
Showing 1 changed file with 59 additions and 28 deletions.
87 changes: 59 additions & 28 deletions src/debug/HyprCtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,46 +1136,77 @@ std::string dispatchSetCursor(eHyprCtlOutputFormat format, std::string request)
}

std::string switchXKBLayoutRequest(eHyprCtlOutputFormat format, std::string request) {
CVarList vars(request, 0, ' ');
CVarList vars(request, 0, ' ');

const auto KB = vars[1];
const auto CMD = vars[2];
const auto KB = vars[1];
const auto CMD = vars[2];

// get kb
const auto PKEYBOARD = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
[&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });
SP<IKeyboard> pKeyboard;

if (PKEYBOARD == g_pInputManager->m_vKeyboards.end())
return "device not found";
auto updateKeyboard = [](const SP<IKeyboard> KEEB, const std::string& CMD) -> std::optional<std::string> {
const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
xkb_layout_index_t activeLayout = 0;
while (activeLayout < LAYOUTS) {
if (xkb_state_layout_index_is_active(KEEB->xkbState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1)
break;

const auto KEEB = *PKEYBOARD;
activeLayout++;
}

const auto LAYOUTS = xkb_keymap_num_layouts(KEEB->xkbKeymap);
xkb_layout_index_t activeLayout = 0;
while (activeLayout < LAYOUTS) {
if (xkb_state_layout_index_is_active(KEEB->xkbState, activeLayout, XKB_STATE_LAYOUT_EFFECTIVE) == 1)
break;
if (CMD == "next")
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, activeLayout > LAYOUTS ? 0 : activeLayout + 1);
else if (CMD == "prev")
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, activeLayout == 0 ? LAYOUTS - 1 : activeLayout - 1);
else {
int requestedLayout = 0;
try {
requestedLayout = std::stoi(CMD);
} catch (std::exception& e) { return "invalid arg 2"; }

if (requestedLayout < 0 || (uint64_t)requestedLayout > LAYOUTS - 1) {
return "layout idx out of range of " + std::to_string(LAYOUTS);
}

activeLayout++;
}
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, requestedLayout);
}

if (CMD == "next")
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, activeLayout > LAYOUTS ? 0 : activeLayout + 1);
else if (CMD == "prev")
KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, activeLayout == 0 ? LAYOUTS - 1 : activeLayout - 1);
else {
int requestedLayout = 0;
try {
requestedLayout = std::stoi(CMD);
} catch (std::exception& e) { return "invalid arg 2"; }
return std::nullopt;
};

if (KB == "main" || KB == "active" || KB == "current") {
for (auto const& k : g_pInputManager->m_vKeyboards) {
if (!k->active)
continue;

if (requestedLayout < 0 || (uint64_t)requestedLayout > LAYOUTS - 1) {
return "layout idx out of range of " + std::to_string(LAYOUTS);
pKeyboard = k;
break;
}
} else if (KB == "all") {
std::string result = "";
for (auto const& k : g_pInputManager->m_vKeyboards) {
auto res = updateKeyboard(k, CMD);
if (res.has_value())
result += *res + "\n";
}
return result.empty() ? "ok" : result;
} else {
auto k = std::find_if(g_pInputManager->m_vKeyboards.begin(), g_pInputManager->m_vKeyboards.end(),
[&](const auto& other) { return other->hlName == g_pInputManager->deviceNameToInternalString(KB); });

if (k == g_pInputManager->m_vKeyboards.end())
return "device not found";

KEEB->updateModifiers(KEEB->modifiersState.depressed, KEEB->modifiersState.latched, KEEB->modifiersState.locked, requestedLayout);
pKeyboard = *k;
}

if (!pKeyboard)
return "no device";

auto result = updateKeyboard(pKeyboard, CMD);

if (result.has_value())
return *result;

return "ok";
}

Expand Down

0 comments on commit d105c74

Please sign in to comment.