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:
src
@@ -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...");
|
||||
|
Reference in New Issue
Block a user