mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 18:50:03 +01:00
Merge branch 'hyprwm:main' into gowno
This commit is contained in:
commit
c4af9d0ce5
7 changed files with 141 additions and 93 deletions
|
|
@ -34,6 +34,17 @@ static bool checkFlag() {
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool attemptCheckFlag(int attempts, int intervalMs) {
|
||||||
|
for (int i = 0; i < attempts; i++) {
|
||||||
|
if (checkFlag())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(intervalMs));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static std::string readKittyOutput() {
|
static std::string readKittyOutput() {
|
||||||
std::string output = Tests::execAndGet("kitten @ --to unix:/tmp/hyprtester-kitty.sock get-text --extent all");
|
std::string output = Tests::execAndGet("kitten @ --to unix:/tmp/hyprtester-kitty.sock get-text --extent all");
|
||||||
// chop off shell prompt
|
// chop off shell prompt
|
||||||
|
|
@ -443,6 +454,34 @@ static void testSubmap() {
|
||||||
Tests::killAllWindows();
|
Tests::killAllWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void testSubmapUniversal() {
|
||||||
|
NLog::log("{}Testing submap universal", Colors::GREEN);
|
||||||
|
|
||||||
|
EXPECT(checkFlag(), false);
|
||||||
|
EXPECT(getFromSocket("/keyword bindu SUPER,Y,exec,touch " + flagFile), "ok");
|
||||||
|
EXPECT_CONTAINS(getFromSocket("/submap"), "default");
|
||||||
|
|
||||||
|
// keybind works on default submap
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:keybind 1,7,29"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:keybind 0,7,29"));
|
||||||
|
EXPECT(attemptCheckFlag(30, 5), true);
|
||||||
|
|
||||||
|
// keybind works on submap1
|
||||||
|
getFromSocket("/dispatch plugin:test:keybind 1,7,30");
|
||||||
|
getFromSocket("/dispatch plugin:test:keybind 0,7,30");
|
||||||
|
EXPECT_CONTAINS(getFromSocket("/submap"), "submap1");
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:keybind 1,7,29"));
|
||||||
|
OK(getFromSocket("/dispatch plugin:test:keybind 0,7,29"));
|
||||||
|
EXPECT(attemptCheckFlag(30, 5), true);
|
||||||
|
|
||||||
|
// reset to default submap
|
||||||
|
getFromSocket("/dispatch plugin:test:keybind 1,0,33");
|
||||||
|
getFromSocket("/dispatch plugin:test:keybind 0,0,33");
|
||||||
|
EXPECT_CONTAINS(getFromSocket("/submap"), "default");
|
||||||
|
|
||||||
|
EXPECT(getFromSocket("/keyword unbind SUPER,Y"), "ok");
|
||||||
|
}
|
||||||
|
|
||||||
static bool test() {
|
static bool test() {
|
||||||
NLog::log("{}Testing keybinds", Colors::GREEN);
|
NLog::log("{}Testing keybinds", Colors::GREEN);
|
||||||
|
|
||||||
|
|
@ -462,8 +501,8 @@ static bool test() {
|
||||||
testShortcutLongPressKeyRelease();
|
testShortcutLongPressKeyRelease();
|
||||||
testShortcutRepeat();
|
testShortcutRepeat();
|
||||||
testShortcutRepeatKeyRelease();
|
testShortcutRepeatKeyRelease();
|
||||||
|
|
||||||
testSubmap();
|
testSubmap();
|
||||||
|
testSubmapUniversal();
|
||||||
|
|
||||||
clearFlag();
|
clearFlag();
|
||||||
return !ret;
|
return !ret;
|
||||||
|
|
|
||||||
|
|
@ -2539,52 +2539,45 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
|
||||||
// bind[fl]=SUPER,G,exec,dmenu_run <args>
|
// bind[fl]=SUPER,G,exec,dmenu_run <args>
|
||||||
|
|
||||||
// flags
|
// flags
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
bool release = false;
|
bool release = false;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
bool mouse = false;
|
bool mouse = false;
|
||||||
bool nonConsuming = false;
|
bool nonConsuming = false;
|
||||||
bool transparent = false;
|
bool transparent = false;
|
||||||
bool ignoreMods = false;
|
bool ignoreMods = false;
|
||||||
bool multiKey = false;
|
bool multiKey = false;
|
||||||
bool longPress = false;
|
bool longPress = false;
|
||||||
bool hasDescription = false;
|
bool hasDescription = false;
|
||||||
bool dontInhibit = false;
|
bool dontInhibit = false;
|
||||||
bool click = false;
|
bool click = false;
|
||||||
bool drag = false;
|
bool drag = false;
|
||||||
const auto BINDARGS = command.substr(4);
|
bool submapUniversal = false;
|
||||||
|
const auto BINDARGS = command.substr(4);
|
||||||
|
|
||||||
for (auto const& arg : BINDARGS) {
|
for (auto const& arg : BINDARGS) {
|
||||||
if (arg == 'l') {
|
switch (arg) {
|
||||||
locked = true;
|
case 'l': locked = true; break;
|
||||||
} else if (arg == 'r') {
|
case 'r': release = true; break;
|
||||||
release = true;
|
case 'e': repeat = true; break;
|
||||||
} else if (arg == 'e') {
|
case 'm': mouse = true; break;
|
||||||
repeat = true;
|
case 'n': nonConsuming = true; break;
|
||||||
} else if (arg == 'm') {
|
case 't': transparent = true; break;
|
||||||
mouse = true;
|
case 'i': ignoreMods = true; break;
|
||||||
} else if (arg == 'n') {
|
case 's': multiKey = true; break;
|
||||||
nonConsuming = true;
|
case 'o': longPress = true; break;
|
||||||
} else if (arg == 't') {
|
case 'd': hasDescription = true; break;
|
||||||
transparent = true;
|
case 'p': dontInhibit = true; break;
|
||||||
} else if (arg == 'i') {
|
case 'c':
|
||||||
ignoreMods = true;
|
click = true;
|
||||||
} else if (arg == 's') {
|
release = true;
|
||||||
multiKey = true;
|
break;
|
||||||
} else if (arg == 'o') {
|
case 'g':
|
||||||
longPress = true;
|
drag = true;
|
||||||
} else if (arg == 'd') {
|
release = true;
|
||||||
hasDescription = true;
|
break;
|
||||||
} else if (arg == 'p') {
|
case 'u': submapUniversal = true; break;
|
||||||
dontInhibit = true;
|
default: return "bind: invalid flag";
|
||||||
} else if (arg == 'c') {
|
|
||||||
click = true;
|
|
||||||
release = true;
|
|
||||||
} else if (arg == 'g') {
|
|
||||||
drag = true;
|
|
||||||
release = true;
|
|
||||||
} else {
|
|
||||||
return "bind: invalid flag";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2657,7 +2650,7 @@ std::optional<std::string> CConfigManager::handleBind(const std::string& command
|
||||||
g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER,
|
g_pKeybindManager->addKeybind(SKeybind{parsedKey.key, KEYSYMS, parsedKey.keycode, parsedKey.catchAll, MOD, MODS, HANDLER,
|
||||||
COMMAND, locked, m_currentSubmap, DESCRIPTION, release, repeat, longPress,
|
COMMAND, locked, m_currentSubmap, DESCRIPTION, release, repeat, longPress,
|
||||||
mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit,
|
mouse, nonConsuming, transparent, ignoreMods, multiKey, hasDescription, dontInhibit,
|
||||||
click, drag});
|
click, drag, submapUniversal});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
||||||
|
|
@ -1025,6 +1025,7 @@ static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request
|
||||||
"has_description": {},
|
"has_description": {},
|
||||||
"modmask": {},
|
"modmask": {},
|
||||||
"submap": "{}",
|
"submap": "{}",
|
||||||
|
"submap_universal": "{}",
|
||||||
"key": "{}",
|
"key": "{}",
|
||||||
"keycode": {},
|
"keycode": {},
|
||||||
"catch_all": {},
|
"catch_all": {},
|
||||||
|
|
@ -1033,8 +1034,9 @@ static std::string bindsRequest(eHyprCtlOutputFormat format, std::string request
|
||||||
"arg": "{}"
|
"arg": "{}"
|
||||||
}},)#",
|
}},)#",
|
||||||
kb->locked ? "true" : "false", kb->mouse ? "true" : "false", kb->release ? "true" : "false", kb->repeat ? "true" : "false", kb->longPress ? "true" : "false",
|
kb->locked ? "true" : "false", kb->mouse ? "true" : "false", kb->release ? "true" : "false", kb->repeat ? "true" : "false", kb->longPress ? "true" : "false",
|
||||||
kb->nonConsuming ? "true" : "false", kb->hasDescription ? "true" : "false", kb->modmask, escapeJSONStrings(kb->submap.name), escapeJSONStrings(kb->key),
|
kb->nonConsuming ? "true" : "false", kb->hasDescription ? "true" : "false", kb->modmask, escapeJSONStrings(kb->submap.name), kb->submapUniversal,
|
||||||
kb->keycode, kb->catchAll ? "true" : "false", escapeJSONStrings(kb->description), escapeJSONStrings(kb->handler), escapeJSONStrings(kb->arg));
|
escapeJSONStrings(kb->key), kb->keycode, kb->catchAll ? "true" : "false", escapeJSONStrings(kb->description), escapeJSONStrings(kb->handler),
|
||||||
|
escapeJSONStrings(kb->arg));
|
||||||
}
|
}
|
||||||
trimTrailingComma(ret);
|
trimTrailingComma(ret);
|
||||||
ret += "]";
|
ret += "]";
|
||||||
|
|
|
||||||
|
|
@ -680,7 +680,7 @@ SDispatchResult CKeybindManager::handleKeybinds(const uint32_t modmask, const SP
|
||||||
if (!k->locked && g_pSessionLockManager->isSessionLocked())
|
if (!k->locked && g_pSessionLockManager->isSessionLocked())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!IGNORECONDITIONS && ((modmask != k->modmask && !k->ignoreMods) || k->submap != m_currentSelectedSubmap || k->shadowed))
|
if (!IGNORECONDITIONS && ((modmask != k->modmask && !k->ignoreMods) || (k->submap != m_currentSelectedSubmap && !k->submapUniversal) || k->shadowed))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (k->multiKey) {
|
if (k->multiKey) {
|
||||||
|
|
|
||||||
|
|
@ -26,29 +26,30 @@ struct SSubmap {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SKeybind {
|
struct SKeybind {
|
||||||
std::string key = "";
|
std::string key = "";
|
||||||
std::set<xkb_keysym_t> sMkKeys = {};
|
std::set<xkb_keysym_t> sMkKeys = {};
|
||||||
uint32_t keycode = 0;
|
uint32_t keycode = 0;
|
||||||
bool catchAll = false;
|
bool catchAll = false;
|
||||||
uint32_t modmask = 0;
|
uint32_t modmask = 0;
|
||||||
std::set<xkb_keysym_t> sMkMods = {};
|
std::set<xkb_keysym_t> sMkMods = {};
|
||||||
std::string handler = "";
|
std::string handler = "";
|
||||||
std::string arg = "";
|
std::string arg = "";
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
SSubmap submap = {};
|
SSubmap submap = {};
|
||||||
std::string description = "";
|
std::string description = "";
|
||||||
bool release = false;
|
bool release = false;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
bool longPress = false;
|
bool longPress = false;
|
||||||
bool mouse = false;
|
bool mouse = false;
|
||||||
bool nonConsuming = false;
|
bool nonConsuming = false;
|
||||||
bool transparent = false;
|
bool transparent = false;
|
||||||
bool ignoreMods = false;
|
bool ignoreMods = false;
|
||||||
bool multiKey = false;
|
bool multiKey = false;
|
||||||
bool hasDescription = false;
|
bool hasDescription = false;
|
||||||
bool dontInhibit = false;
|
bool dontInhibit = false;
|
||||||
bool click = false;
|
bool click = false;
|
||||||
bool drag = false;
|
bool drag = false;
|
||||||
|
bool submapUniversal = false;
|
||||||
|
|
||||||
// DO NOT INITIALIZE
|
// DO NOT INITIALIZE
|
||||||
bool shadowed = false;
|
bool shadowed = false;
|
||||||
|
|
|
||||||
|
|
@ -120,11 +120,18 @@ void CInputPopup::updateBox() {
|
||||||
CBox cursorBoxLocal({-popupOffset.x, -popupOffset.y}, cursorBoxParent.size());
|
CBox cursorBoxLocal({-popupOffset.x, -popupOffset.y}, cursorBoxParent.size());
|
||||||
m_popup->sendInputRectangle(cursorBoxLocal);
|
m_popup->sendInputRectangle(cursorBoxLocal);
|
||||||
|
|
||||||
CBox popupBoxParent(cursorBoxParent.pos() + popupOffset, currentPopupSize);
|
CBox popupBoxParent(cursorBoxParent.pos() + popupOffset, currentPopupSize);
|
||||||
if (popupBoxParent != m_lastBoxLocal) {
|
const bool boxChanged = popupBoxParent != m_lastBoxLocal;
|
||||||
|
if (boxChanged)
|
||||||
|
damageEntire(); // damage the old location before updating
|
||||||
|
|
||||||
|
m_lastBoxLocal = popupBoxParent;
|
||||||
|
|
||||||
|
// Since a redraw request is not always sent when only the position is updated,
|
||||||
|
// a manual redraw may be required in some cases.
|
||||||
|
if (boxChanged)
|
||||||
damageEntire();
|
damageEntire();
|
||||||
m_lastBoxLocal = popupBoxParent;
|
|
||||||
}
|
|
||||||
damageSurface();
|
damageSurface();
|
||||||
|
|
||||||
if (const auto PM = g_pCompositor->getMonitorFromCursor(); PM && PM->m_id != m_lastMonitor) {
|
if (const auto PM = g_pCompositor->getMonitorFromCursor(); PM && PM->m_id != m_lastMonitor) {
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,24 @@ void CScreencopyFrame::renderMon() {
|
||||||
g_pHyprOpenGL->setRenderModifEnabled(true);
|
g_pHyprOpenGL->setRenderModifEnabled(true);
|
||||||
g_pHyprOpenGL->popMonitorTransformEnabled();
|
g_pHyprOpenGL->popMonitorTransformEnabled();
|
||||||
|
|
||||||
|
auto hidePopups = [&](Vector2D popupBaseOffset) {
|
||||||
|
return [&, popupBaseOffset](WP<CPopup> popup, void*) {
|
||||||
|
if (!popup->m_wlSurface || !popup->m_wlSurface->resource() || !popup->m_mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto popRel = popup->coordsRelativeToParent();
|
||||||
|
popup->m_wlSurface->resource()->breadthfirst(
|
||||||
|
[&](SP<CWLSurfaceResource> surf, const Vector2D& localOff, void*) {
|
||||||
|
const auto size = surf->m_current.size;
|
||||||
|
const auto surfBox = CBox{popupBaseOffset + popRel + localOff, size}.translate(m_monitor->m_position).scale(m_monitor->m_scale).translate(-m_box.pos());
|
||||||
|
|
||||||
|
if LIKELY (surfBox.w > 0 && surfBox.h > 0)
|
||||||
|
g_pHyprOpenGL->renderRect(surfBox, Colors::BLACK, {});
|
||||||
|
},
|
||||||
|
nullptr);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
for (auto const& l : g_pCompositor->m_layers) {
|
for (auto const& l : g_pCompositor->m_layers) {
|
||||||
if (!l->m_noScreenShare)
|
if (!l->m_noScreenShare)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -225,6 +243,10 @@ void CScreencopyFrame::renderMon() {
|
||||||
CBox{REALPOS.x, REALPOS.y, std::max(REALSIZE.x, 5.0), std::max(REALSIZE.y, 5.0)}.translate(-m_monitor->m_position).scale(m_monitor->m_scale).translate(-m_box.pos());
|
CBox{REALPOS.x, REALPOS.y, std::max(REALSIZE.x, 5.0), std::max(REALSIZE.y, 5.0)}.translate(-m_monitor->m_position).scale(m_monitor->m_scale).translate(-m_box.pos());
|
||||||
|
|
||||||
g_pHyprOpenGL->renderRect(noScreenShareBox, Colors::BLACK, {});
|
g_pHyprOpenGL->renderRect(noScreenShareBox, Colors::BLACK, {});
|
||||||
|
|
||||||
|
const auto geom = l->m_geometry;
|
||||||
|
const Vector2D popupBaseOffset = REALPOS - Vector2D{geom.pos().x, geom.pos().y};
|
||||||
|
l->m_popupHead->breadthfirst(hidePopups(popupBaseOffset), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& w : g_pCompositor->m_windows) {
|
for (auto const& w : g_pCompositor->m_windows) {
|
||||||
|
|
@ -261,23 +283,7 @@ void CScreencopyFrame::renderMon() {
|
||||||
const auto geom = w->m_xdgSurface->m_current.geometry;
|
const auto geom = w->m_xdgSurface->m_current.geometry;
|
||||||
const Vector2D popupBaseOffset = REALPOS - Vector2D{geom.pos().x, geom.pos().y};
|
const Vector2D popupBaseOffset = REALPOS - Vector2D{geom.pos().x, geom.pos().y};
|
||||||
|
|
||||||
w->m_popupHead->breadthfirst(
|
w->m_popupHead->breadthfirst(hidePopups(popupBaseOffset), nullptr);
|
||||||
[&](WP<CPopup> popup, void*) {
|
|
||||||
if (!popup->m_wlSurface || !popup->m_wlSurface->resource() || !popup->m_mapped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto popRel = popup->coordsRelativeToParent();
|
|
||||||
popup->m_wlSurface->resource()->breadthfirst(
|
|
||||||
[&](SP<CWLSurfaceResource> surf, const Vector2D& localOff, void*) {
|
|
||||||
const auto size = surf->m_current.size;
|
|
||||||
const auto surfBox = CBox{popupBaseOffset + popRel + localOff, size}.translate(-m_monitor->m_position).scale(m_monitor->m_scale).translate(-m_box.pos());
|
|
||||||
|
|
||||||
if LIKELY (surfBox.w > 0 && surfBox.h > 0)
|
|
||||||
g_pHyprOpenGL->renderRect(surfBox, Colors::BLACK, {});
|
|
||||||
},
|
|
||||||
nullptr);
|
|
||||||
},
|
|
||||||
nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_overlayCursor)
|
if (m_overlayCursor)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue