pointermgr: fix initial cursorwarp (#7286)

change the hook to monitorAdded instead of newMonitor so its finalized
in the compositor and added to vMonitors, move the
checkDefaultCursorWarp to PointerManager and check for it upon mode
change. and also ensure it doesnt go out of bounds by replacing it in
the middle again on resolution changes.
This commit is contained in:
Tom Englund 2024-08-11 20:42:18 +02:00 committed by GitHub
parent 01ff5fdf6a
commit 511eea71c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 39 deletions

View file

@ -2918,39 +2918,6 @@ PHLWINDOW CCompositor::windowForCPointer(CWindow* pWindow) {
return {}; return {};
} }
static void checkDefaultCursorWarp(SP<CMonitor> PNEWMONITOR, std::string monitorName) {
static auto PCURSORMONITOR = CConfigValue<std::string>("cursor:default_monitor");
static auto firstMonitorAdded = std::chrono::system_clock::now();
static bool cursorDefaultDone = false;
static bool firstLaunch = true;
const auto POS = PNEWMONITOR->middle();
// by default, cursor should be set to first monitor detected
// this is needed as a default if the monitor given in config above doesn't exist
if (firstLaunch) {
firstLaunch = false;
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
}
if (cursorDefaultDone || *PCURSORMONITOR == STRVAL_EMPTY)
return;
// after 10s, don't set cursor to default monitor
auto timePassedSec = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - firstMonitorAdded);
if (timePassedSec.count() > 10) {
cursorDefaultDone = true;
return;
}
if (*PCURSORMONITOR == monitorName) {
cursorDefaultDone = true;
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
}
}
void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) { void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
// add it to real // add it to real
auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>()); auto PNEWMONITOR = g_pCompositor->m_vRealMonitors.emplace_back(makeShared<CMonitor>());
@ -2986,8 +2953,6 @@ void CCompositor::onNewMonitor(SP<Aquamarine::IOutput> output) {
g_pConfigManager->m_bWantsMonitorReload = true; g_pConfigManager->m_bWantsMonitorReload = true;
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR); g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR.get(), IOutput::AQ_SCHEDULE_NEW_MONITOR);
checkDefaultCursorWarp(PNEWMONITOR, output->name);
for (auto& w : g_pCompositor->m_vWindows) { for (auto& w : g_pCompositor->m_vWindows) {
if (w->m_iMonitorID == PNEWMONITOR->ID) { if (w->m_iMonitorID == PNEWMONITOR->ID) {
w->m_iLastSurfaceMonitorID = MONITOR_INVALID; w->m_iLastSurfaceMonitorID = MONITOR_INVALID;

View file

@ -11,13 +11,21 @@
#include <gbm.h> #include <gbm.h>
CPointerManager::CPointerManager() { CPointerManager::CPointerManager() {
hooks.monitorAdded = g_pHookSystem->hookDynamic("newMonitor", [this](void* self, SCallbackInfo& info, std::any data) { hooks.monitorAdded = g_pHookSystem->hookDynamic("monitorAdded", [this](void* self, SCallbackInfo& info, std::any data) {
auto PMONITOR = std::any_cast<SP<CMonitor>>(data); auto PMONITOR = std::any_cast<CMonitor*>(data)->self.lock();
onMonitorLayoutChange(); onMonitorLayoutChange();
PMONITOR->events.modeChanged.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); PMONITOR->events.modeChanged.registerStaticListener(
PMONITOR->events.disconnect.registerStaticListener([this](void* owner, std::any data) { g_pEventLoopManager->doLater([this]() { onMonitorLayoutChange(); }); }, nullptr); [this, PMONITOR](void* owner, std::any data) {
g_pEventLoopManager->doLater([this, PMONITOR]() {
onMonitorLayoutChange();
checkDefaultCursorWarp(PMONITOR, PMONITOR->output->name);
});
},
nullptr);
PMONITOR->events.disconnect.registerStaticListener(
[this, PMONITOR](void* owner, std::any data) { g_pEventLoopManager->doLater([this, PMONITOR]() { onMonitorLayoutChange(); }); }, nullptr);
PMONITOR->events.destroy.registerStaticListener( PMONITOR->events.destroy.registerStaticListener(
[this](void* owner, std::any data) { [this](void* owner, std::any data) {
if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown) if (g_pCompositor && !g_pCompositor->m_bIsShuttingDown)
@ -35,6 +43,38 @@ CPointerManager::CPointerManager() {
}); });
} }
void CPointerManager::checkDefaultCursorWarp(SP<CMonitor> monitor, std::string monitorName) {
static auto PCURSORMONITOR = CConfigValue<std::string>("cursor:default_monitor");
static bool cursorDefaultDone = false;
static bool firstLaunch = true;
const auto POS = monitor->middle();
// by default, cursor should be set to first monitor detected
// this is needed as a default if the monitor given in config above doesn't exist
if (firstLaunch) {
firstLaunch = false;
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
return;
}
if (!cursorDefaultDone && *PCURSORMONITOR != STRVAL_EMPTY) {
if (*PCURSORMONITOR == monitorName) {
cursorDefaultDone = true;
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
return;
}
}
// modechange happend check if cursor is on that monitor and warp it to middle to not place it out of bounds if resolution changed.
if (g_pCompositor->getMonitorFromCursor() == monitor.get()) {
g_pCompositor->warpCursorTo(POS, true);
g_pInputManager->refocus();
}
}
void CPointerManager::lockSoftwareAll() { void CPointerManager::lockSoftwareAll() {
for (auto& state : monitorStates) for (auto& state : monitorStates)
state->softwareLocks++; state->softwareLocks++;

View file

@ -26,6 +26,7 @@ class CPointerManager {
public: public:
CPointerManager(); CPointerManager();
void checkDefaultCursorWarp(SP<CMonitor> monitor, std::string monitorName);
void attachPointer(SP<IPointer> pointer); void attachPointer(SP<IPointer> pointer);
void attachTouch(SP<ITouch> touch); void attachTouch(SP<ITouch> touch);
void attachTablet(SP<CTablet> tablet); void attachTablet(SP<CTablet> tablet);