better foreign toplevel protocol obedience

This commit is contained in:
Vaxry 2022-08-06 20:57:38 +02:00
parent ccd68049f7
commit 69b8568ccf
8 changed files with 101 additions and 18 deletions

View File

@ -1349,6 +1349,8 @@ void CCompositor::moveWorkspaceToMonitor(CWorkspace* pWorkspace, CMonitor* pMoni
if (w->m_bIsFloating && w->m_bIsMapped && !w->m_bHidden) {
w->m_vRealPosition = w->m_vRealPosition.vec() - POLDMON->vecPosition + pMonitor->vecPosition;
}
w->updateToplevel();
}
}
@ -1541,3 +1543,16 @@ SLayerSurface* CCompositor::getLayerSurfaceFromWlr(wlr_layer_surface_v1* pLS) {
return nullptr;
}
void CCompositor::closeWindow(CWindow* pWindow) {
if (pWindow && windowValidMapped(pWindow)) {
g_pXWaylandManager->sendCloseWindow(pWindow);
if (pWindow == m_pLastWindow) {
g_pCompositor->m_pLastFocus = nullptr;
g_pCompositor->m_pLastWindow = nullptr;
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // post an activewindow event to empty, as we are currently unfocused
g_pCompositor->focusWindow(g_pCompositor->windowFromCursor());
}
}
}

View File

@ -156,6 +156,7 @@ public:
CWindow* getWindowByRegex(const std::string&);
void warpCursorTo(const Vector2D&);
SLayerSurface* getLayerSurfaceFromWlr(wlr_layer_surface_v1*);
void closeWindow(CWindow*);
std::string explicitConfigPath;

View File

@ -112,4 +112,63 @@ IHyprWindowDecoration* CWindow::getDecorationByType(eDecorationType type) {
}
return nullptr;
}
void CWindow::createToplevelHandle() {
if (m_bIsX11 && (m_bX11DoesntWantBorders || m_iX11Type == 2))
return; // don't create a toplevel
m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
wlr_foreign_toplevel_handle_v1_set_app_id(m_phForeignToplevel, g_pXWaylandManager->getAppIDClass(this).c_str());
wlr_foreign_toplevel_handle_v1_output_enter(m_phForeignToplevel, g_pCompositor->getMonitorFromID(m_iMonitorID)->output);
wlr_foreign_toplevel_handle_v1_set_title(m_phForeignToplevel, m_szTitle.c_str());
wlr_foreign_toplevel_handle_v1_set_maximized(m_phForeignToplevel, false);
wlr_foreign_toplevel_handle_v1_set_minimized(m_phForeignToplevel, false);
wlr_foreign_toplevel_handle_v1_set_fullscreen(m_phForeignToplevel, false);
// handle events
hyprListener_toplevelActivate.initCallback(&m_phForeignToplevel->events.request_activate, [&](void* owner, void* data) {
g_pCompositor->focusWindow(this);
}, this, "Toplevel");
hyprListener_toplevelFullscreen.initCallback(&m_phForeignToplevel->events.request_fullscreen, [&](void* owner, void* data) {
const auto EV = (wlr_foreign_toplevel_handle_v1_fullscreen_event*)data;
g_pCompositor->setWindowFullscreen(this, EV->fullscreen, FULLSCREEN_FULL);
}, this, "Toplevel");
hyprListener_toplevelClose.initCallback(&m_phForeignToplevel->events.request_close, [&](void* owner, void* data) {
g_pCompositor->closeWindow(this);
}, this, "Toplevel");
m_iLastToplevelMonitorID = m_iMonitorID;
}
void CWindow::destroyToplevelHandle() {
hyprListener_toplevelActivate.removeCallback();
hyprListener_toplevelClose.removeCallback();
hyprListener_toplevelFullscreen.removeCallback();
wlr_foreign_toplevel_handle_v1_destroy(m_phForeignToplevel);
m_phForeignToplevel = nullptr;
}
void CWindow::updateToplevel() {
wlr_foreign_toplevel_handle_v1_set_app_id(m_phForeignToplevel, g_pXWaylandManager->getAppIDClass(this).c_str());
wlr_foreign_toplevel_handle_v1_set_title(m_phForeignToplevel, m_szTitle.c_str());
wlr_foreign_toplevel_handle_v1_set_fullscreen(m_phForeignToplevel, m_bIsFullscreen);
if (m_iLastToplevelMonitorID != m_iMonitorID) {
wlr_foreign_toplevel_handle_v1_output_leave(m_phForeignToplevel, g_pCompositor->getMonitorFromID(m_iLastToplevelMonitorID)->output);
wlr_foreign_toplevel_handle_v1_output_enter(m_phForeignToplevel, g_pCompositor->getMonitorFromID(m_iMonitorID)->output);
m_iLastToplevelMonitorID = m_iMonitorID;
}
}

View File

@ -39,6 +39,11 @@ public:
DYNLISTENER(requestMinimize);
DYNLISTENER(requestMaximize);
DYNLISTENER(requestResize);
DYNLISTENER(activateX11);
DYNLISTENER(configureX11);
DYNLISTENER(toplevelClose);
DYNLISTENER(toplevelActivate);
DYNLISTENER(toplevelFullscreen);
// DYNLISTENER(newSubsurfaceWindow);
union {
@ -87,8 +92,6 @@ public:
uint64_t m_iX11Type = 0;
bool m_bIsModal = false;
bool m_bX11DoesntWantBorders = false;
DYNLISTENER(activateX11);
DYNLISTENER(configureX11);
//
// For nofocus
@ -127,6 +130,9 @@ public:
// animated shadow color
CAnimatedVariable m_cRealShadowColor;
// for toplevel monitor events
int m_iLastToplevelMonitorID = -1;
// For the list lookup
bool operator==(const CWindow& rhs) {
return m_uSurface.xdg == rhs.m_uSurface.xdg && m_uSurface.xwayland == rhs.m_uSurface.xwayland && m_vPosition == rhs.m_vPosition && m_vSize == rhs.m_vSize && m_bFadingOut == rhs.m_bFadingOut;
@ -138,5 +144,8 @@ public:
void updateWindowDecos();
pid_t getPID();
IHyprWindowDecoration* getDecorationByType(eDecorationType);
void createToplevelHandle();
void destroyToplevelHandle();
void updateToplevel();
};

View File

@ -68,9 +68,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
// Foreign Toplevel
PWINDOW->m_phForeignToplevel = wlr_foreign_toplevel_handle_v1_create(g_pCompositor->m_sWLRToplevelMgr);
// TODO: handle foreign events (requests)
wlr_foreign_toplevel_handle_v1_set_app_id(PWINDOW->m_phForeignToplevel, g_pXWaylandManager->getAppIDClass(PWINDOW).c_str());
PWINDOW->createToplevelHandle();
// checks if the window wants borders and sets the appriopriate flag
g_pXWaylandManager->checkBorders(PWINDOW);
@ -327,6 +325,8 @@ void Events::listener_mapWindow(void* owner, void* data) {
PWINDOW->m_pSurfaceTree = SubsurfaceTree::createTreeRoot(g_pXWaylandManager->getWindowSurface(PWINDOW), addViewCoords, PWINDOW, PWINDOW);
PWINDOW->updateToplevel();
Debug::log(LOG, "Map request dispatched, monitor %s, xywh: %f %f %f %f", PMONITOR->szName.c_str(), PWINDOW->m_vRealPosition.goalv().x, PWINDOW->m_vRealPosition.goalv().y, PWINDOW->m_vRealSize.goalv().x, PWINDOW->m_vRealSize.goalv().y);
}
@ -412,8 +412,7 @@ void Events::listener_unmapWindow(void* owner, void* data) {
PWINDOW->m_fAlpha = 0.f;
// Destroy Foreign Toplevel
wlr_foreign_toplevel_handle_v1_destroy(PWINDOW->m_phForeignToplevel);
PWINDOW->m_phForeignToplevel = nullptr;
PWINDOW->destroyToplevelHandle();
// recheck idle inhibitors
g_pInputManager->recheckIdleInhibitorStatus();
@ -469,8 +468,7 @@ void Events::listener_setTitleWindow(void* owner, void* data) {
if (PWINDOW == g_pCompositor->m_pLastWindow) // if it's the active, let's post an event to update others
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", g_pXWaylandManager->getAppIDClass(PWINDOW) + "," + PWINDOW->m_szTitle});
if (PWINDOW->m_phForeignToplevel)
wlr_foreign_toplevel_handle_v1_set_title(PWINDOW->m_phForeignToplevel, PWINDOW->m_szTitle.c_str());
PWINDOW->updateToplevel();
Debug::log(LOG, "Window %x set title to %s", PWINDOW, PWINDOW->m_szTitle.c_str());
}
@ -489,6 +487,8 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
g_pLayoutManager->getCurrentLayout()->fullscreenRequestForWindow(PWINDOW, FULLSCREEN_FULL, !PWINDOW->m_bIsFullscreen);
}
PWINDOW->updateToplevel();
Debug::log(LOG, "Window %x fullscreen to %i", PWINDOW, PWINDOW->m_bIsFullscreen);
g_pXWaylandManager->setWindowFullscreen(PWINDOW, PWINDOW->m_bIsFullscreen);

View File

@ -202,6 +202,8 @@ void IHyprLayout::onMouseMove(const Vector2D& mousePos) {
if (PMONITOR) {
DRAGGINGWINDOW->m_iMonitorID = PMONITOR->ID;
DRAGGINGWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
DRAGGINGWINDOW->updateToplevel();
}
DRAGGINGWINDOW->updateWindowDecos();
@ -257,6 +259,8 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
pWindow->m_sSpecialRenderData.rounding = true;
}
pWindow->updateToplevel();
}
void IHyprLayout::moveActiveWindow(const Vector2D& delta, CWindow* pWindow) {

View File

@ -408,14 +408,7 @@ void CKeybindManager::spawn(std::string args) {
}
void CKeybindManager::killActive(std::string args) {
if (g_pCompositor->m_pLastWindow && g_pCompositor->windowValidMapped(g_pCompositor->m_pLastWindow)) {
g_pXWaylandManager->sendCloseWindow(g_pCompositor->m_pLastWindow);
g_pCompositor->m_pLastFocus = nullptr;
g_pCompositor->m_pLastWindow = nullptr;
g_pEventManager->postEvent(SHyprIPCEvent{"activewindow", ","}); // post an activewindow event to empty, as we are currently unfocused
}
g_pCompositor->focusWindow(g_pCompositor->windowFromCursor());
g_pCompositor->closeWindow(g_pCompositor->m_pLastWindow);
}
void CKeybindManager::clearKeybinds() {
@ -671,6 +664,8 @@ void CKeybindManager::moveActiveToWorkspace(std::string args) {
}
g_pInputManager->refocus();
PWINDOW->updateToplevel();
}
void CKeybindManager::moveActiveToWorkspaceSilent(std::string args) {

@ -1 +1 @@
Subproject commit b24b50ec0c1c54a14acf34df2c95b37043d15b49
Subproject commit 7b5e890e61a27375725068a7d1884b26851b3102