mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-10-14 22:15:58 +00:00
input: always allow focus to permission popups
This commit is contained in:
@@ -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 PBORDERGRABEXTEND = CConfigValue<Hyprlang::INT>("general:extend_border_grab_area");
|
||||||
static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
static auto PSPECIALFALLTHRU = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
||||||
const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
|
const auto BORDER_GRAB_AREA = *PRESIZEONBORDER ? *PBORDERSIZE + *PBORDERGRABEXTEND : 0;
|
||||||
|
const bool ONLY_PRIORITY = properties & FOCUS_PRIORITY;
|
||||||
|
|
||||||
// pinned windows on top of floating regardless
|
// pinned windows on top of floating regardless
|
||||||
if (properties & ALLOW_FLOATING) {
|
if (properties & ALLOW_FLOATING) {
|
||||||
for (auto const& w : m_windows | std::views::reverse) {
|
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) {
|
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);
|
const auto BB = w->getWindowBoxUnified(properties);
|
||||||
CBox box = BB.copy().expand(!w->isX11OverrideRedirect() ? BORDER_GRAB_AREA : 0);
|
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)
|
if (!w->m_workspace)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||||
|
continue;
|
||||||
|
|
||||||
const auto PWINDOWMONITOR = w->m_monitor.lock();
|
const auto PWINDOWMONITOR = w->m_monitor.lock();
|
||||||
|
|
||||||
// to avoid focusing windows behind special workspaces from other monitors
|
// 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 WORKSPACEID WSPID = special ? PMONITOR->activeSpecialWorkspaceID() : PMONITOR->activeWorkspaceID();
|
||||||
const auto PWORKSPACE = getWorkspaceByID(WSPID);
|
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();
|
return PWORKSPACE->getFullscreenWindow();
|
||||||
|
|
||||||
auto found = floating(false);
|
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 windows, we need to check their extensions too, first.
|
||||||
for (auto const& w : m_windows) {
|
for (auto const& w : m_windows) {
|
||||||
|
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (special != w->onSpecialWorkspace())
|
if (special != w->onSpecialWorkspace())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -973,6 +983,9 @@ PHLWINDOW CCompositor::vectorToWindowUnified(const Vector2D& pos, uint8_t proper
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& w : m_windows) {
|
for (auto const& w : m_windows) {
|
||||||
|
if (ONLY_PRIORITY && !w->priorityFocus())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (special != w->onSpecialWorkspace())
|
if (special != w->onSpecialWorkspace())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -1083,6 +1096,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||||||
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
static auto PFOLLOWMOUSE = CConfigValue<Hyprlang::INT>("input:follow_mouse");
|
||||||
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
static auto PSPECIALFALLTHROUGH = CConfigValue<Hyprlang::INT>("input:special_fallthrough");
|
||||||
|
|
||||||
|
if (!pWindow || !pWindow->priorityFocus()) {
|
||||||
if (g_pSessionLockManager->isSessionLocked()) {
|
if (g_pSessionLockManager->isSessionLocked()) {
|
||||||
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
|
Debug::log(LOG, "Refusing a keyboard focus to a window because of a sessionlock");
|
||||||
return;
|
return;
|
||||||
@@ -1092,6 +1106,7 @@ void CCompositor::focusWindow(PHLWINDOW pWindow, SP<CWLSurfaceResource> pSurface
|
|||||||
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
|
Debug::log(LOG, "Refusing a keyboard focus to a window because of an exclusive ls");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
|
if (pWindow && pWindow->m_isX11 && pWindow->isX11OverrideRedirect() && !pWindow->m_xwaylandSurface->wantsFocus())
|
||||||
return;
|
return;
|
||||||
|
@@ -1836,3 +1836,7 @@ PHLWINDOW CWindow::parent() {
|
|||||||
|
|
||||||
return m_xdgSurface->m_toplevel->m_parent->m_window.lock();
|
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,
|
ALLOW_FLOATING = 1 << 4,
|
||||||
USE_PROP_TILED = 1 << 5,
|
USE_PROP_TILED = 1 << 5,
|
||||||
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
|
SKIP_FULLSCREEN_PRIORITY = 1 << 6,
|
||||||
|
FOCUS_PRIORITY = 1 << 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eSuppressEvents : uint8_t {
|
enum eSuppressEvents : uint8_t {
|
||||||
@@ -408,6 +409,7 @@ class CWindow {
|
|||||||
std::optional<std::string> xdgTag();
|
std::optional<std::string> xdgTag();
|
||||||
std::optional<std::string> xdgDescription();
|
std::optional<std::string> xdgDescription();
|
||||||
PHLWINDOW parent();
|
PHLWINDOW parent();
|
||||||
|
bool priorityFocus();
|
||||||
|
|
||||||
CBox getWindowMainSurfaceBox() const {
|
CBox getWindowMainSurfaceBox() const {
|
||||||
return {m_realPosition->value().x, m_realPosition->value().y, m_realSize->value().x, m_realSize->value().y};
|
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;
|
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) {
|
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) {
|
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) :
|
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.");
|
Debug::log(LOG, "CAsyncDialogBox: dialog {:x} hung up, closed.");
|
||||||
|
|
||||||
m_promiseResolver->resolve(m_stdout);
|
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);
|
wl_event_source_remove(m_readEventSource);
|
||||||
m_selfReference.reset();
|
m_selfReference.reset();
|
||||||
@@ -112,7 +123,7 @@ SP<CPromise<std::string>> CAsyncDialogBox::open() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_dialogPid = proc.pid();
|
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 the write fd, only the dialog owns it now
|
||||||
close(outPipe[1]);
|
close(outPipe[1]);
|
||||||
|
@@ -16,6 +16,7 @@ class CAsyncDialogBox {
|
|||||||
public:
|
public:
|
||||||
static SP<CAsyncDialogBox> create(const std::string& title, const std::string& description, std::vector<std::string> buttons);
|
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 isAsyncDialogBox(pid_t pid);
|
||||||
|
static bool isPriorityDialogBox(pid_t pid);
|
||||||
|
|
||||||
CAsyncDialogBox(const CAsyncDialogBox&) = delete;
|
CAsyncDialogBox(const CAsyncDialogBox&) = delete;
|
||||||
CAsyncDialogBox(CAsyncDialogBox&&) = delete;
|
CAsyncDialogBox(CAsyncDialogBox&&) = delete;
|
||||||
@@ -26,6 +27,9 @@ class CAsyncDialogBox {
|
|||||||
void kill();
|
void kill();
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
|
|
||||||
|
// focus priority, only permission popups
|
||||||
|
bool m_priority = false;
|
||||||
|
|
||||||
void onWrite(int fd, uint32_t mask);
|
void onWrite(int fd, uint32_t mask);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -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())
|
if (PMONITOR != g_pCompositor->m_lastMonitor && (*PMOUSEFOCUSMON || refocus) && m_forcedFocus.expired())
|
||||||
g_pCompositor->setActiveMonitor(PMONITOR);
|
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
|
// set keyboard focus on session lock surface regardless of layers
|
||||||
const auto PSESSIONLOCKSURFACE = g_pSessionLockManager->getSessionLockSurfaceForMonitor(PMONITOR->m_id);
|
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)
|
if (!forcedFocus)
|
||||||
forcedFocus = g_pCompositor->getForceFocus();
|
forcedFocus = g_pCompositor->getForceFocus();
|
||||||
|
|
||||||
if (forcedFocus) {
|
if (forcedFocus && !foundSurface) {
|
||||||
pFoundWindow = forcedFocus;
|
pFoundWindow = forcedFocus;
|
||||||
surfacePos = pFoundWindow->m_realPosition->value();
|
surfacePos = pFoundWindow->m_realPosition->value();
|
||||||
foundSurface = pFoundWindow->m_wlSurface->resource();
|
foundSurface = pFoundWindow->m_wlSurface->resource();
|
||||||
|
@@ -297,6 +297,7 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s
|
|||||||
options = {"Deny", "Allow"};
|
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) {
|
if (!rule->m_dialogBox) {
|
||||||
Debug::log(ERR, "CDynamicPermissionManager::askForPermission: hyprland-qtutils likely missing, cannot ask! Disabling permission control...");
|
Debug::log(ERR, "CDynamicPermissionManager::askForPermission: hyprland-qtutils likely missing, cannot ask! Disabling permission control...");
|
||||||
|
Reference in New Issue
Block a user