1
0
mirror of https://github.com/hyprwm/Hyprland.git synced 2025-08-14 11:35:46 -07:00

input: always allow focus to permission popups

This commit is contained in:
Vaxry
2025-05-18 19:34:14 +02:00
parent 158c0f2911
commit d9c8a37811
7 changed files with 58 additions and 16 deletions

@@ -870,10 +870,14 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
static auto PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
const bool ONLY_PRIORITY = properties & FOCUS_PRIORITY;
// pinned windows on top of floating regardless
if (properties & ALLOW_FLOATING) {
for (auto const& w : m_windows | std::views::reverse) {
if (ONLY_PRIORITY && !w->priorityFocus())
continue;
if (w->m_isFloating && w->m_isMapped && !w->isHidden() && !w->m_X11ShouldntFocus && w->m_pinned && !w->m_windowData.noFocus.valueOrDefault() && w != pIgnoreWindow) {
const auto BB = w->getWindowBoxUnified(properties);
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
@@ -898,6 +902,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
if (!w->m_workspace)
continue;
if (ONLY_PRIORITY && !w->priorityFocus())
continue;
const auto PWINDOWMONITOR = w->m_monitor.lock();
// to avoid focusing windows behind special workspaces from other monitors
@@ -950,7 +957,7 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
const WORKSPACEID WSPID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID();
const auto PWORKSPACE = getWorkspaceByID(WSPID);
if (PWORKSPACE->m_hasFullscreenWindow && !(properties & SKIP_FULLSCREEN_PRIORITY))
if (PWORKSPACE->m_hasFullscreenWindow && !(properties & SKIP_FULLSCREEN_PRIORITY) && !ONLY_PRIORITY)
return PWORKSPACE->getFullscreenWindow();
auto found = floating(false);
@@ -959,6 +966,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
// for windows, we need to check their extensions too, first.
for (auto const& w : m_windows) {
if (ONLY_PRIORITY && !w->priorityFocus())
continue;
if (special != w->onSpecialWorkspace())
continue;
@@ -973,6 +983,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
}
for (auto const& w : m_windows) {
if (ONLY_PRIORITY && !w->priorityFocus())
continue;
if (special != w->onSpecialWorkspace())
continue;
@@ -1083,14 +1096,16 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return;
}
if (!pWindow || !pWindow->priorityFocus()) {
if (g_pSessionLockManager->isSessionLocked()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
return;
}
if (!g_pInputManager->m_exclusiveLSes.empty()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
if (!g_pInputManager->m_exclusiveLSes.empty()) {
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
return;
}
}
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())

@@ -1836,3 +1836,7 @@ PHLWINDOW CWindow::parent() {
return m_xdgSurface->m_toplevel->m_parent->m_window.lock();
}
bool CWindow::priorityFocus() {
return !m_isX11 && CAsyncDialogBox::isPriorityDialogBox(getPID());
}

@@ -51,6 +51,7 @@ enum eGetWindowProperties : uint8_t {
ALLOW_FLOATING = 1 << 4,
USE_PROP_TILED = 1 << 5,
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
FOCUS_PRIORITY = 1 << 7,
};
enum eSuppressEvents : uint8_t {
@@ -408,6 +409,7 @@ class CWindow {
std::optional<std::string> xdgTag();
std::optional<std::string> xdgDescription();
PHLWINDOW parent();
bool priorityFocus();
CBox getWindowMainSurfaceBox() const {
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};

@@ -7,7 +7,7 @@
using namespace Hyprutils::OS;
static std::vector<pid_t> asyncDialogBoxes;
static std::vector<std::pair<pid_t, WP<CAsyncDialogBox>>> asyncDialogBoxes;
//
SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std::string& description, std::vector<std::string> buttons) {
@@ -24,7 +24,18 @@ SP<CAsyncDialogBox> CAsyncDialogBox::create(const std::string& title, const std:
}
bool CAsyncDialogBox::isAsyncDialogBox(pid_t pid) {
return std::ranges::contains(asyncDialogBoxes, pid);
return std::ranges::find_if(asyncDialogBoxes, [pid](const auto& e) { return e.first == pid; }) != asyncDialogBoxes.end();
}
bool CAsyncDialogBox::isPriorityDialogBox(pid_t pid) {
for (const auto& [p, db] : asyncDialogBoxes) {
if (p != pid)
continue;
return db && db->m_priority;
}
return false;
}
CAsyncDialogBox::CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons) :
@@ -68,7 +79,7 @@ void CAsyncDialogBox::onWrite(int fd, uint32_t mask) {
Debug::log(LOG, "CAsyncDialogBox: dialog {:x} hung up, closed.");
m_promiseResolver->resolve(m_stdout);
std::erase(asyncDialogBoxes, m_dialogPid);
std::erase_if(asyncDialogBoxes, [this](const auto& e) { return e.first == m_dialogPid; });
wl_event_source_remove(m_readEventSource);
m_selfReference.reset();
@@ -112,7 +123,7 @@ SP<CPromise<std::string>> CAsyncDialogBox::open() {
}
m_dialogPid = proc.pid();
asyncDialogBoxes.emplace_back(m_dialogPid);
asyncDialogBoxes.emplace_back(std::make_pair<>(m_dialogPid, m_selfWeakReference));
// close the write fd, only the dialog owns it now
close(outPipe[1]);

@@ -16,6 +16,7 @@ class CAsyncDialogBox {
public:
static SP<CAsyncDialogBox> create(const std::string& title, const std::string& description, std::vector<std::string> buttons);
static bool isAsyncDialogBox(pid_t pid);
static bool isPriorityDialogBox(pid_t pid);
CAsyncDialogBox(const CAsyncDialogBox&) = delete;
CAsyncDialogBox(CAsyncDialogBox&&) = delete;
@@ -26,7 +27,10 @@ class CAsyncDialogBox {
void kill();
bool isRunning() const;
void onWrite(int fd, uint32_t mask);
// focus priority, only permission popups
bool m_priority = false;
void onWrite(int fd, uint32_t mask);
private:
CAsyncDialogBox(const std::string& title, const std::string& description, std::vector<std::string> buttons);

@@ -250,7 +250,12 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
if (PMONITOR != g_pCompositor->m_lastMonitor && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
g_pCompositor->setActiveMonitor(PMONITOR);
if (g_pSessionLockManager->isSessionLocked()) {
// check for windows that have focus priority like our permission popups
pFoundWindow = g_pCompositor->vectorToWindowUnified(mouseCoords, FOCUS_PRIORITY);
if (pFoundWindow)
foundSurface = g_pCompositor->vectorWindowToSurface(mouseCoords, pFoundWindow, surfaceCoords);
if (!foundSurface && g_pSessionLockManager->isSessionLocked()) {
// set keyboard focus on session lock surface regardless of layers
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
@@ -288,7 +293,7 @@ void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
if (!forcedFocus)
forcedFocus = g_pCompositor->getForceFocus();
if (forcedFocus) {
if (forcedFocus && !foundSurface) {
pFoundWindow = forcedFocus;
surfacePos = pFoundWindow->m_realPosition->value();
foundSurface = pFoundWindow->m_wlSurface->resource();

@@ -296,7 +296,8 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
} else
options = {"Deny", "Allow"};
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
rule->m_dialogBox = CAsyncDialogBox::create("Permission request", description, options);
rule->m_dialogBox->m_priority = true;
if (!rule->m_dialogBox) {
Debug::log(ERR, "CDynamicPermissionManager::askForPermission: hyprland-qtutils likely missing, cannot ask! Disabling permission control...");