mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 12:06:00 +01:00
wlr-foreign-toplevel: move to new impl
This commit is contained in:
parent
72e31d3335
commit
ecf282d331
15 changed files with 477 additions and 166 deletions
|
@ -252,7 +252,6 @@ target_link_libraries(Hyprland
|
||||||
protocol("protocols/idle.xml" "idle" true)
|
protocol("protocols/idle.xml" "idle" true)
|
||||||
protocol("protocols/pointer-constraints-unstable-v1.xml" "pointer-constraints-unstable-v1" true)
|
protocol("protocols/pointer-constraints-unstable-v1.xml" "pointer-constraints-unstable-v1" true)
|
||||||
protocol("protocols/tablet-unstable-v2.xml" "tablet-unstable-v2" true)
|
protocol("protocols/tablet-unstable-v2.xml" "tablet-unstable-v2" true)
|
||||||
protocol("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
|
||||||
protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true)
|
protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true)
|
||||||
protocol("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
protocol("protocols/wlr-output-power-management-unstable-v1.xml" "wlr-output-power-management-unstable-v1" true)
|
||||||
protocol("protocols/wlr-screencopy-unstable-v1.xml" "wlr-screencopy-unstable-v1" true)
|
protocol("protocols/wlr-screencopy-unstable-v1.xml" "wlr-screencopy-unstable-v1" true)
|
||||||
|
@ -263,6 +262,7 @@ protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unst
|
||||||
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
||||||
|
|
||||||
protocolNew("protocols/wlr-gamma-control-unstable-v1.xml" "wlr-gamma-control-unstable-v1" true)
|
protocolNew("protocols/wlr-gamma-control-unstable-v1.xml" "wlr-gamma-control-unstable-v1" true)
|
||||||
|
protocolNew("protocols/wlr-foreign-toplevel-management-unstable-v1.xml" "wlr-foreign-toplevel-management-unstable-v1" true)
|
||||||
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
|
protocolNew("staging/tearing-control/tearing-control-v1.xml" "tearing-control-v1" false)
|
||||||
protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
protocolNew("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||||
protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
protocolNew("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
||||||
|
|
|
@ -27,7 +27,6 @@ protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
||||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
['wlr-output-power-management-unstable-v1.xml'],
|
['wlr-output-power-management-unstable-v1.xml'],
|
||||||
['wlr-screencopy-unstable-v1.xml'],
|
['wlr-screencopy-unstable-v1.xml'],
|
||||||
|
@ -40,6 +39,7 @@ protocols = [
|
||||||
|
|
||||||
new_protocols = [
|
new_protocols = [
|
||||||
['wlr-gamma-control-unstable-v1.xml'],
|
['wlr-gamma-control-unstable-v1.xml'],
|
||||||
|
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
[wl_protocol_dir, 'staging/tearing-control/tearing-control-v1.xml'],
|
||||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||||
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||||
|
|
|
@ -219,8 +219,6 @@ void CCompositor::initServer() {
|
||||||
|
|
||||||
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
m_sWLRVirtPtrMgr = wlr_virtual_pointer_manager_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRToplevelMgr = wlr_foreign_toplevel_manager_v1_create(m_sWLDisplay);
|
|
||||||
|
|
||||||
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
|
m_sWRLDRMLeaseMgr = wlr_drm_lease_v1_manager_create(m_sWLDisplay, m_sWLRBackend);
|
||||||
if (!m_sWRLDRMLeaseMgr) {
|
if (!m_sWRLDRMLeaseMgr) {
|
||||||
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
|
Debug::log(INFO, "Failed to create wlr_drm_lease_v1_manager");
|
||||||
|
@ -954,9 +952,6 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||||
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
updateWindowAnimatedDecorationValues(PLASTWINDOW);
|
||||||
|
|
||||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||||
|
|
||||||
if (PLASTWINDOW->m_phForeignToplevel)
|
|
||||||
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
wlr_seat_keyboard_notify_clear_focus(m_sSeat.seat);
|
||||||
|
@ -1016,9 +1011,6 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||||
|
|
||||||
if (!pWindow->m_bIsX11 || pWindow->m_iX11Type == 1)
|
if (!pWindow->m_bIsX11 || pWindow->m_iX11Type == 1)
|
||||||
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
g_pXWaylandManager->activateWindow(PLASTWINDOW, false);
|
||||||
|
|
||||||
if (PLASTWINDOW->m_phForeignToplevel)
|
|
||||||
wlr_foreign_toplevel_handle_v1_set_activated(PLASTWINDOW->m_phForeignToplevel, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pLastWindow = PLASTWINDOW;
|
m_pLastWindow = PLASTWINDOW;
|
||||||
|
@ -1044,17 +1036,6 @@ void CCompositor::focusWindow(CWindow* pWindow, wlr_surface* pSurface) {
|
||||||
|
|
||||||
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
|
g_pLayoutManager->getCurrentLayout()->onWindowFocusChange(pWindow);
|
||||||
|
|
||||||
// TODO: implement this better
|
|
||||||
if (!PLASTWINDOW && pWindow->m_sGroupData.pNextWindow) {
|
|
||||||
for (auto curr = pWindow->m_sGroupData.pNextWindow; curr != pWindow; curr = curr->m_sGroupData.pNextWindow) {
|
|
||||||
if (curr->m_phForeignToplevel)
|
|
||||||
wlr_foreign_toplevel_handle_v1_set_activated(curr->m_phForeignToplevel, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pWindow->m_phForeignToplevel)
|
|
||||||
wlr_foreign_toplevel_handle_v1_set_activated(pWindow->m_phForeignToplevel, true);
|
|
||||||
|
|
||||||
g_pInputManager->recheckIdleInhibitorStatus();
|
g_pInputManager->recheckIdleInhibitorStatus();
|
||||||
|
|
||||||
// move to front of the window history
|
// move to front of the window history
|
||||||
|
@ -1203,23 +1184,6 @@ CWindow* CCompositor::getWindowFromHandle(uint32_t handle) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getWindowFromZWLRHandle(wl_resource* handle) {
|
|
||||||
for (auto& w : m_vWindows) {
|
|
||||||
if (!w->m_bIsMapped || w->isHidden() || !w->m_phForeignToplevel)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wl_resource* current;
|
|
||||||
|
|
||||||
wl_list_for_each(current, &w->m_phForeignToplevel->resources, link) {
|
|
||||||
if (current == handle) {
|
|
||||||
return w.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) {
|
CWindow* CCompositor::getFullscreenWindowOnWorkspace(const int& ID) {
|
||||||
for (auto& w : m_vWindows) {
|
for (auto& w : m_vWindows) {
|
||||||
if (w->workspaceID() == ID && w->m_bIsFullscreen)
|
if (w->workspaceID() == ID && w->m_bIsFullscreen)
|
||||||
|
|
|
@ -66,7 +66,6 @@ class CCompositor {
|
||||||
wlr_pointer_constraints_v1* m_sWLRPointerConstraints;
|
wlr_pointer_constraints_v1* m_sWLRPointerConstraints;
|
||||||
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
wlr_server_decoration_manager* m_sWLRServerDecoMgr;
|
||||||
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
wlr_virtual_pointer_manager_v1* m_sWLRVirtPtrMgr;
|
||||||
wlr_foreign_toplevel_manager_v1* m_sWLRToplevelMgr;
|
|
||||||
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
wlr_tablet_manager_v2* m_sWLRTabletManager;
|
||||||
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
wlr_xdg_foreign_registry* m_sWLRForeignRegistry;
|
||||||
wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
|
wlr_output_power_manager_v1* m_sWLROutputPowerMgr;
|
||||||
|
@ -136,7 +135,6 @@ class CCompositor {
|
||||||
CMonitor* getRealMonitorFromOutput(wlr_output*);
|
CMonitor* getRealMonitorFromOutput(wlr_output*);
|
||||||
CWindow* getWindowFromSurface(wlr_surface*);
|
CWindow* getWindowFromSurface(wlr_surface*);
|
||||||
CWindow* getWindowFromHandle(uint32_t);
|
CWindow* getWindowFromHandle(uint32_t);
|
||||||
CWindow* getWindowFromZWLRHandle(wl_resource*);
|
|
||||||
bool isWorkspaceVisible(PHLWORKSPACE);
|
bool isWorkspaceVisible(PHLWORKSPACE);
|
||||||
PHLWORKSPACE getWorkspaceByID(const int&);
|
PHLWORKSPACE getWorkspaceByID(const int&);
|
||||||
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
PHLWORKSPACE getWorkspaceByName(const std::string&);
|
||||||
|
|
|
@ -274,66 +274,8 @@ IHyprWindowDecoration* CWindow::getDecorationByType(eDecorationType type) {
|
||||||
return nullptr;
|
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_pLayoutManager->getCurrentLayout()->requestFocusForWindow(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() {
|
|
||||||
if (!m_phForeignToplevel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hyprListener_toplevelActivate.removeCallback();
|
|
||||||
hyprListener_toplevelClose.removeCallback();
|
|
||||||
hyprListener_toplevelFullscreen.removeCallback();
|
|
||||||
|
|
||||||
wlr_foreign_toplevel_handle_v1_destroy(m_phForeignToplevel);
|
|
||||||
m_phForeignToplevel = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWindow::updateToplevel() {
|
void CWindow::updateToplevel() {
|
||||||
updateSurfaceScaleTransformDetails();
|
updateSurfaceScaleTransformDetails();
|
||||||
|
|
||||||
if (!m_phForeignToplevel)
|
|
||||||
return;
|
|
||||||
|
|
||||||
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) {
|
|
||||||
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(m_iLastToplevelMonitorID); PMONITOR && PMONITOR->m_bEnabled)
|
|
||||||
wlr_foreign_toplevel_handle_v1_output_leave(m_phForeignToplevel, PMONITOR->output);
|
|
||||||
wlr_foreign_toplevel_handle_v1_output_enter(m_phForeignToplevel, g_pCompositor->getMonitorFromID(m_iMonitorID)->output);
|
|
||||||
|
|
||||||
m_iLastToplevelMonitorID = m_iMonitorID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendEnterIter(wlr_surface* pSurface, int x, int y, void* data) {
|
void sendEnterIter(wlr_surface* pSurface, int x, int y, void* data) {
|
||||||
|
@ -1311,3 +1253,21 @@ std::unordered_map<std::string, std::string> CWindow::getEnv() {
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWindow::activate() {
|
||||||
|
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
|
||||||
|
|
||||||
|
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)this)});
|
||||||
|
EMIT_HOOK_EVENT("urgent", this);
|
||||||
|
|
||||||
|
m_bIsUrgent = true;
|
||||||
|
|
||||||
|
if (!*PFOCUSONACTIVATE || (m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_bIsFloating)
|
||||||
|
g_pCompositor->changeWindowZOrder(this, true);
|
||||||
|
|
||||||
|
g_pCompositor->focusWindow(this);
|
||||||
|
g_pCompositor->warpCursorTo(middle());
|
||||||
|
}
|
||||||
|
|
|
@ -328,9 +328,6 @@ class CWindow {
|
||||||
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
// for proper cycling. While cycling we can't just move the pointers, so we need to keep track of the last cycled window.
|
||||||
CWindow* m_pLastCycledWindow = nullptr;
|
CWindow* m_pLastCycledWindow = nullptr;
|
||||||
|
|
||||||
// Foreign Toplevel proto
|
|
||||||
wlr_foreign_toplevel_handle_v1* m_phForeignToplevel = nullptr;
|
|
||||||
|
|
||||||
// Window decorations
|
// Window decorations
|
||||||
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
std::deque<std::unique_ptr<IHyprWindowDecoration>> m_dWindowDecorations;
|
||||||
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
std::vector<IHyprWindowDecoration*> m_vDecosToRemove;
|
||||||
|
@ -398,8 +395,6 @@ class CWindow {
|
||||||
pid_t getPID();
|
pid_t getPID();
|
||||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||||
void removeDecorationByType(eDecorationType);
|
void removeDecorationByType(eDecorationType);
|
||||||
void createToplevelHandle();
|
|
||||||
void destroyToplevelHandle();
|
|
||||||
void updateToplevel();
|
void updateToplevel();
|
||||||
void updateSurfaceScaleTransformDetails();
|
void updateSurfaceScaleTransformDetails();
|
||||||
void moveToWorkspace(PHLWORKSPACE);
|
void moveToWorkspace(PHLWORKSPACE);
|
||||||
|
@ -420,6 +415,7 @@ class CWindow {
|
||||||
bool visibleOnMonitor(CMonitor* pMonitor);
|
bool visibleOnMonitor(CMonitor* pMonitor);
|
||||||
int workspaceID();
|
int workspaceID();
|
||||||
bool onSpecialWorkspace();
|
bool onSpecialWorkspace();
|
||||||
|
void activate();
|
||||||
|
|
||||||
int getRealBorderSize();
|
int getRealBorderSize();
|
||||||
void updateSpecialRenderData();
|
void updateSpecialRenderData();
|
||||||
|
|
|
@ -110,9 +110,6 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||||
// Set all windows tiled regardless of anything
|
// Set all windows tiled regardless of anything
|
||||||
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
g_pXWaylandManager->setWindowStyleTiled(PWINDOW, WLR_EDGE_LEFT | WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM);
|
||||||
|
|
||||||
// Foreign Toplevel
|
|
||||||
PWINDOW->createToplevelHandle();
|
|
||||||
|
|
||||||
// checks if the window wants borders and sets the appropriate flag
|
// checks if the window wants borders and sets the appropriate flag
|
||||||
g_pXWaylandManager->checkBorders(PWINDOW);
|
g_pXWaylandManager->checkBorders(PWINDOW);
|
||||||
|
|
||||||
|
@ -786,9 +783,6 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||||
PWINDOW->m_fAlpha = 0.f;
|
PWINDOW->m_fAlpha = 0.f;
|
||||||
|
|
||||||
// Destroy Foreign Toplevel
|
|
||||||
PWINDOW->destroyToplevelHandle();
|
|
||||||
|
|
||||||
// recheck idle inhibitors
|
// recheck idle inhibitors
|
||||||
g_pInputManager->recheckIdleInhibitorStatus();
|
g_pInputManager->recheckIdleInhibitorStatus();
|
||||||
|
|
||||||
|
@ -1015,8 +1009,6 @@ void Events::listener_fullscreenWindow(void* owner, void* data) {
|
||||||
void Events::listener_activateXDG(wl_listener* listener, void* data) {
|
void Events::listener_activateXDG(wl_listener* listener, void* data) {
|
||||||
const auto E = (wlr_xdg_activation_v1_request_activate_event*)data;
|
const auto E = (wlr_xdg_activation_v1_request_activate_event*)data;
|
||||||
|
|
||||||
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
|
|
||||||
|
|
||||||
Debug::log(LOG, "Activate request for surface at {:x}", (uintptr_t)E->surface);
|
Debug::log(LOG, "Activate request for surface at {:x}", (uintptr_t)E->surface);
|
||||||
|
|
||||||
if (!wlr_xdg_surface_try_from_wlr_surface(E->surface))
|
if (!wlr_xdg_surface_try_from_wlr_surface(E->surface))
|
||||||
|
@ -1027,26 +1019,12 @@ void Events::listener_activateXDG(wl_listener* listener, void* data) {
|
||||||
if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
if (!PWINDOW || PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)});
|
PWINDOW->activate();
|
||||||
EMIT_HOOK_EVENT("urgent", PWINDOW);
|
|
||||||
|
|
||||||
PWINDOW->m_bIsUrgent = true;
|
|
||||||
|
|
||||||
if (!*PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFloating)
|
|
||||||
g_pCompositor->changeWindowZOrder(PWINDOW, true);
|
|
||||||
|
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
|
||||||
g_pCompositor->warpCursorTo(PWINDOW->middle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_activateX11(void* owner, void* data) {
|
void Events::listener_activateX11(void* owner, void* data) {
|
||||||
const auto PWINDOW = (CWindow*)owner;
|
const auto PWINDOW = (CWindow*)owner;
|
||||||
|
|
||||||
static auto PFOCUSONACTIVATE = CConfigValue<Hyprlang::INT>("misc:focus_on_activate");
|
|
||||||
|
|
||||||
Debug::log(LOG, "X11 Activate request for window {}", PWINDOW);
|
Debug::log(LOG, "X11 Activate request for window {}", PWINDOW);
|
||||||
|
|
||||||
if (PWINDOW->m_iX11Type == 2) {
|
if (PWINDOW->m_iX11Type == 2) {
|
||||||
|
@ -1066,17 +1044,7 @@ void Events::listener_activateX11(void* owner, void* data) {
|
||||||
if (PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
if (PWINDOW == g_pCompositor->m_pLastWindow || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_pEventManager->postEvent(SHyprIPCEvent{"urgent", std::format("{:x}", (uintptr_t)PWINDOW)});
|
PWINDOW->activate();
|
||||||
EMIT_HOOK_EVENT("urgent", PWINDOW);
|
|
||||||
|
|
||||||
if (!*PFOCUSONACTIVATE || (PWINDOW->m_eSuppressedEvents & SUPPRESS_ACTIVATE_FOCUSONLY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (PWINDOW->m_bIsFloating)
|
|
||||||
g_pCompositor->changeWindowZOrder(PWINDOW, true);
|
|
||||||
|
|
||||||
g_pCompositor->focusWindow(PWINDOW);
|
|
||||||
g_pCompositor->warpCursorTo(PWINDOW->middle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_configureX11(void* owner, void* data) {
|
void Events::listener_configureX11(void* owner, void* data) {
|
||||||
|
@ -1275,9 +1243,8 @@ void Events::listener_requestMaximize(void* owner, void* data) {
|
||||||
|
|
||||||
Debug::log(LOG, "Maximize request for {}", PWINDOW);
|
Debug::log(LOG, "Maximize request for {}", PWINDOW);
|
||||||
if (!PWINDOW->m_bIsX11) {
|
if (!PWINDOW->m_bIsX11) {
|
||||||
const auto EV = (wlr_foreign_toplevel_handle_v1_maximized_event*)data;
|
|
||||||
|
|
||||||
g_pCompositor->setWindowFullscreen(PWINDOW, EV ? EV->maximized : !PWINDOW->m_bIsFullscreen,
|
g_pCompositor->setWindowFullscreen(PWINDOW, !PWINDOW->m_bIsFullscreen,
|
||||||
FULLSCREEN_MAXIMIZED); // this will be rejected if there already is a fullscreen window
|
FULLSCREEN_MAXIMIZED); // this will be rejected if there already is a fullscreen window
|
||||||
|
|
||||||
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
wlr_xdg_surface_schedule_configure(PWINDOW->m_uSurface.xdg);
|
||||||
|
@ -1305,9 +1272,8 @@ void Events::listener_requestMinimize(void* owner, void* data) {
|
||||||
|
|
||||||
wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK
|
wlr_xwayland_surface_set_minimized(PWINDOW->m_uSurface.xwayland, E->minimize && g_pCompositor->m_pLastWindow != PWINDOW); // fucking DXVK
|
||||||
} else {
|
} else {
|
||||||
const auto E = (wlr_foreign_toplevel_handle_v1_minimized_event*)data;
|
g_pEventManager->postEvent({"minimize", std::format("{:x},{}", (uintptr_t)PWINDOW, 1)});
|
||||||
g_pEventManager->postEvent({"minimize", std::format("{:x},{}", (uintptr_t)PWINDOW, E ? (int)E->minimized : 1)});
|
EMIT_HOOK_EVENT("minimize", (std::vector<void*>{PWINDOW, (void*)(1)}));
|
||||||
EMIT_HOOK_EVENT("minimize", (std::vector<void*>{PWINDOW, (void*)(E ? (uint64_t)E->minimized : 1)}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,6 @@ extern "C" {
|
||||||
#include <wlr/types/wlr_damage_ring.h>
|
#include <wlr/types/wlr_damage_ring.h>
|
||||||
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
|
||||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||||
#include <wlr/types/wlr_foreign_toplevel_management_v1.h>
|
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/util/region.h>
|
#include <wlr/util/region.h>
|
||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../protocols/GammaControl.hpp"
|
#include "../protocols/GammaControl.hpp"
|
||||||
#include "../protocols/ForeignToplevel.hpp"
|
#include "../protocols/ForeignToplevel.hpp"
|
||||||
#include "../protocols/PointerGestures.hpp"
|
#include "../protocols/PointerGestures.hpp"
|
||||||
|
#include "../protocols/ForeignToplevelWlr.hpp"
|
||||||
|
|
||||||
#include "tearing-control-v1.hpp"
|
#include "tearing-control-v1.hpp"
|
||||||
#include "fractional-scale-v1.hpp"
|
#include "fractional-scale-v1.hpp"
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
#include "wlr-gamma-control-unstable-v1.hpp"
|
#include "wlr-gamma-control-unstable-v1.hpp"
|
||||||
#include "ext-foreign-toplevel-list-v1.hpp"
|
#include "ext-foreign-toplevel-list-v1.hpp"
|
||||||
#include "pointer-gestures-unstable-v1.hpp"
|
#include "pointer-gestures-unstable-v1.hpp"
|
||||||
|
#include "wlr-foreign-toplevel-management-unstable-v1.hpp"
|
||||||
|
|
||||||
CProtocolManager::CProtocolManager() {
|
CProtocolManager::CProtocolManager() {
|
||||||
|
|
||||||
|
@ -37,6 +39,7 @@ CProtocolManager::CProtocolManager() {
|
||||||
PROTO::gamma = std::make_unique<CGammaControlProtocol>(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
|
PROTO::gamma = std::make_unique<CGammaControlProtocol>(&zwlr_gamma_control_manager_v1_interface, 1, "GammaControl");
|
||||||
PROTO::foreignToplevel = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
|
PROTO::foreignToplevel = std::make_unique<CForeignToplevelProtocol>(&ext_foreign_toplevel_list_v1_interface, 1, "ForeignToplevel");
|
||||||
PROTO::pointerGestures = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
|
PROTO::pointerGestures = std::make_unique<CPointerGesturesProtocol>(&zwp_pointer_gestures_v1_interface, 3, "PointerGestures");
|
||||||
|
PROTO::foreignToplevelWlr = std::make_unique<CForeignToplevelWlrProtocol>(&zwlr_foreign_toplevel_manager_v1_interface, 3, "ForeignToplevelWlr");
|
||||||
|
|
||||||
// Old protocol implementations.
|
// Old protocol implementations.
|
||||||
// TODO: rewrite them to use hyprwayland-scanner.
|
// TODO: rewrite them to use hyprwayland-scanner.
|
||||||
|
|
|
@ -295,9 +295,6 @@ void CHyprXWaylandManager::setWindowFullscreen(CWindow* pWindow, bool fullscreen
|
||||||
wlr_xwayland_surface_set_fullscreen(pWindow->m_uSurface.xwayland, fullscreen);
|
wlr_xwayland_surface_set_fullscreen(pWindow->m_uSurface.xwayland, fullscreen);
|
||||||
else
|
else
|
||||||
wlr_xdg_toplevel_set_fullscreen(pWindow->m_uSurface.xdg->toplevel, fullscreen);
|
wlr_xdg_toplevel_set_fullscreen(pWindow->m_uSurface.xdg->toplevel, fullscreen);
|
||||||
|
|
||||||
if (pWindow->m_phForeignToplevel)
|
|
||||||
wlr_foreign_toplevel_handle_v1_set_fullscreen(pWindow->m_phForeignToplevel, fullscreen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
|
Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
|
||||||
|
|
|
@ -62,6 +62,8 @@ void CForeignToplevelList::onMap(CWindow* pWindow) {
|
||||||
NEWHANDLE->resource->sendAppId(pWindow->m_szInitialClass.c_str());
|
NEWHANDLE->resource->sendAppId(pWindow->m_szInitialClass.c_str());
|
||||||
NEWHANDLE->resource->sendTitle(pWindow->m_szInitialTitle.c_str());
|
NEWHANDLE->resource->sendTitle(pWindow->m_szInitialTitle.c_str());
|
||||||
NEWHANDLE->resource->sendDone();
|
NEWHANDLE->resource->sendDone();
|
||||||
|
|
||||||
|
handles.push_back(NEWHANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SP<CForeignToplevelHandle> CForeignToplevelList::handleForWindow(CWindow* pWindow) {
|
SP<CForeignToplevelHandle> CForeignToplevelList::handleForWindow(CWindow* pWindow) {
|
||||||
|
|
354
src/protocols/ForeignToplevelWlr.cpp
Normal file
354
src/protocols/ForeignToplevelWlr.cpp
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
#include "ForeignToplevelWlr.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
|
#define LOGM PROTO::foreignToplevelWlr->protoLog
|
||||||
|
|
||||||
|
CForeignToplevelHandleWlr::CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, CWindow* pWindow_) : resource(resource_), pWindow(pWindow_) {
|
||||||
|
if (!resource_->resource())
|
||||||
|
return;
|
||||||
|
|
||||||
|
resource->setOnDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); });
|
||||||
|
resource->setDestroy([this](CZwlrForeignToplevelHandleV1* h) { PROTO::foreignToplevelWlr->destroyHandle(this); });
|
||||||
|
|
||||||
|
resource->setActivate([this](CZwlrForeignToplevelHandleV1* p, wl_resource* seat) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_eSuppressedEvents & SUPPRESS_ACTIVATE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pWindow->activate();
|
||||||
|
});
|
||||||
|
|
||||||
|
resource->setSetFullscreen([this](CZwlrForeignToplevelHandleV1* p, wl_resource* output) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pWindow->m_bIsMapped) {
|
||||||
|
pWindow->m_bWantsInitialFullscreen = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
resource->setUnsetFullscreen([this](CZwlrForeignToplevelHandleV1* p) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_eSuppressedEvents & SUPPRESS_FULLSCREEN)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
resource->setSetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pWindow->m_bIsMapped) {
|
||||||
|
pWindow->m_bWantsInitialFullscreen = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, true, FULLSCREEN_MAXIMIZED);
|
||||||
|
});
|
||||||
|
|
||||||
|
resource->setUnsetMaximized([this](CZwlrForeignToplevelHandleV1* p) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pWindow->m_eSuppressedEvents & SUPPRESS_MAXIMIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pCompositor->setWindowFullscreen(pWindow, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
resource->setClose([this](CZwlrForeignToplevelHandleV1* p) {
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_pCompositor->closeWindow(pWindow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CForeignToplevelHandleWlr::good() {
|
||||||
|
return resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
CWindow* CForeignToplevelHandleWlr::window() {
|
||||||
|
return pWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource* CForeignToplevelHandleWlr::res() {
|
||||||
|
return resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelHandleWlr::sendMonitor(CMonitor* pMonitor) {
|
||||||
|
if (lastMonitorID == (int64_t)pMonitor->ID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto CLIENT = wl_resource_get_client(resource->resource());
|
||||||
|
|
||||||
|
struct wl_resource* outputResource;
|
||||||
|
|
||||||
|
if (const auto PLASTMONITOR = g_pCompositor->getMonitorFromID(lastMonitorID); PLASTMONITOR) {
|
||||||
|
wl_resource_for_each(outputResource, &PLASTMONITOR->output->resources) {
|
||||||
|
if (wl_resource_get_client(outputResource) != CLIENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
resource->sendOutputLeave(outputResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_resource_for_each(outputResource, &pMonitor->output->resources) {
|
||||||
|
if (wl_resource_get_client(outputResource) != CLIENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
resource->sendOutputEnter(outputResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastMonitorID = pMonitor->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelHandleWlr::sendState() {
|
||||||
|
if (!pWindow || !pWindow->m_pWorkspace || !pWindow->m_bIsMapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wl_array state;
|
||||||
|
wl_array_init(&state);
|
||||||
|
|
||||||
|
if (pWindow == g_pCompositor->m_pLastWindow) {
|
||||||
|
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
|
||||||
|
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pWindow->m_bIsFullscreen) {
|
||||||
|
auto p = (uint32_t*)wl_array_add(&state, sizeof(uint32_t));
|
||||||
|
if (pWindow->m_pWorkspace->m_efFullscreenMode == FULLSCREEN_FULL)
|
||||||
|
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN;
|
||||||
|
else
|
||||||
|
*p = ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
resource->sendState(&state);
|
||||||
|
|
||||||
|
wl_array_release(&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
CForeignToplevelWlrManager::CForeignToplevelWlrManager(SP<CZwlrForeignToplevelManagerV1> resource_) : resource(resource_) {
|
||||||
|
if (!resource_->resource())
|
||||||
|
return;
|
||||||
|
|
||||||
|
resource->setOnDestroy([this](CZwlrForeignToplevelManagerV1* h) { PROTO::foreignToplevelWlr->onManagerResourceDestroy(this); });
|
||||||
|
|
||||||
|
resource->setStop([this](CZwlrForeignToplevelManagerV1* h) {
|
||||||
|
resource->sendFinished();
|
||||||
|
finished = true;
|
||||||
|
LOGM(LOG, "CForeignToplevelWlrManager: finished");
|
||||||
|
PROTO::foreignToplevelWlr->onManagerResourceDestroy(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto& w : g_pCompositor->m_vWindows) {
|
||||||
|
if (!w->m_bIsMapped || w->m_bFadingOut)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
onMap(w.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
lastFocus = g_pCompositor->m_pLastWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onMap(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto NEWHANDLE = PROTO::foreignToplevelWlr->m_vHandles.emplace_back(std::make_shared<CForeignToplevelHandleWlr>(
|
||||||
|
std::make_shared<CZwlrForeignToplevelHandleV1>(wl_resource_get_client(resource->resource()), wl_resource_get_version(resource->resource()), 0), pWindow));
|
||||||
|
|
||||||
|
if (!NEWHANDLE->good()) {
|
||||||
|
LOGM(ERR, "Couldn't create a foreign handle");
|
||||||
|
wl_resource_post_no_memory(resource->resource());
|
||||||
|
PROTO::foreignToplevelWlr->m_vHandles.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGM(LOG, "Newly mapped window {:016x}", (uintptr_t)pWindow);
|
||||||
|
resource->sendToplevel(NEWHANDLE->resource.get());
|
||||||
|
NEWHANDLE->resource->sendAppId(pWindow->m_szInitialClass.c_str());
|
||||||
|
NEWHANDLE->resource->sendTitle(pWindow->m_szInitialTitle.c_str());
|
||||||
|
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); PMONITOR)
|
||||||
|
NEWHANDLE->sendMonitor(PMONITOR);
|
||||||
|
NEWHANDLE->sendState();
|
||||||
|
NEWHANDLE->resource->sendDone();
|
||||||
|
|
||||||
|
handles.push_back(NEWHANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SP<CForeignToplevelHandleWlr> CForeignToplevelWlrManager::handleForWindow(CWindow* pWindow) {
|
||||||
|
std::erase_if(handles, [](const auto& wp) { return !wp.lock(); });
|
||||||
|
const auto IT = std::find_if(handles.begin(), handles.end(), [pWindow](const auto& h) { return h.lock()->window() == pWindow; });
|
||||||
|
return IT == handles.end() ? SP<CForeignToplevelHandleWlr>{} : IT->lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onTitle(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H || H->closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->resource->sendTitle(pWindow->m_szTitle.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onClass(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H || H->closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->resource->sendAppId(g_pXWaylandManager->getAppIDClass(pWindow).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onUnmap(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->resource->sendClosed();
|
||||||
|
H->closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onMoveMonitor(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H || H->closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
|
||||||
|
|
||||||
|
if (!PMONITOR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->sendMonitor(PMONITOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onFullscreen(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H || H->closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->sendState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrManager::onNewFocus(CWindow* pWindow) {
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (const auto HOLD = handleForWindow(lastFocus); HOLD)
|
||||||
|
HOLD->sendState();
|
||||||
|
|
||||||
|
lastFocus = pWindow;
|
||||||
|
|
||||||
|
const auto H = handleForWindow(pWindow);
|
||||||
|
if (!H || H->closed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
H->sendState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CForeignToplevelWlrManager::good() {
|
||||||
|
return resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
CForeignToplevelWlrProtocol::CForeignToplevelWlrProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||||
|
static auto P = g_pHookSystem->hookDynamic("openWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onMap(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
static auto P1 = g_pHookSystem->hookDynamic("closeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onUnmap(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
static auto P2 = g_pHookSystem->hookDynamic("windowTitle", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onTitle(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
static auto P3 = g_pHookSystem->hookDynamic("activeWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onNewFocus(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
static auto P4 = g_pHookSystem->hookDynamic("moveWindow", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onMoveMonitor(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
static auto P5 = g_pHookSystem->hookDynamic("fullscreen", [this](void* self, SCallbackInfo& info, std::any data) {
|
||||||
|
const auto PWINDOW = std::any_cast<CWindow*>(data);
|
||||||
|
for (auto& m : m_vManagers) {
|
||||||
|
m->onFullscreen(PWINDOW);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||||
|
const auto RESOURCE = m_vManagers.emplace_back(std::make_unique<CForeignToplevelWlrManager>(std::make_shared<CZwlrForeignToplevelManagerV1>(client, ver, id))).get();
|
||||||
|
|
||||||
|
if (!RESOURCE->good()) {
|
||||||
|
LOGM(ERR, "Couldn't create a foreign list");
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
m_vManagers.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrProtocol::onManagerResourceDestroy(CForeignToplevelWlrManager* mgr) {
|
||||||
|
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == mgr; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForeignToplevelWlrProtocol::destroyHandle(CForeignToplevelHandleWlr* handle) {
|
||||||
|
std::erase_if(m_vHandles, [&](const auto& other) { return other.get() == handle; });
|
||||||
|
}
|
||||||
|
|
||||||
|
CWindow* CForeignToplevelWlrProtocol::windowFromHandleResource(wl_resource* res) {
|
||||||
|
for (auto& h : m_vHandles) {
|
||||||
|
if (h->res() != res)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return h->window();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
77
src/protocols/ForeignToplevelWlr.hpp
Normal file
77
src/protocols/ForeignToplevelWlr.hpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "WaylandProtocol.hpp"
|
||||||
|
#include "wlr-foreign-toplevel-management-unstable-v1.hpp"
|
||||||
|
|
||||||
|
class CWindow;
|
||||||
|
class CMonitor;
|
||||||
|
|
||||||
|
class CForeignToplevelHandleWlr {
|
||||||
|
public:
|
||||||
|
CForeignToplevelHandleWlr(SP<CZwlrForeignToplevelHandleV1> resource_, CWindow* pWindow);
|
||||||
|
|
||||||
|
bool good();
|
||||||
|
CWindow* window();
|
||||||
|
wl_resource* res();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SP<CZwlrForeignToplevelHandleV1> resource;
|
||||||
|
CWindow* pWindow = nullptr;
|
||||||
|
bool closed = false;
|
||||||
|
int64_t lastMonitorID = -1;
|
||||||
|
|
||||||
|
void sendMonitor(CMonitor* pMonitor);
|
||||||
|
void sendState();
|
||||||
|
|
||||||
|
friend class CForeignToplevelWlrManager;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CForeignToplevelWlrManager {
|
||||||
|
public:
|
||||||
|
CForeignToplevelWlrManager(SP<CZwlrForeignToplevelManagerV1> resource_);
|
||||||
|
|
||||||
|
void onMap(CWindow* pWindow);
|
||||||
|
void onTitle(CWindow* pWindow);
|
||||||
|
void onClass(CWindow* pWindow);
|
||||||
|
void onMoveMonitor(CWindow* pWindow);
|
||||||
|
void onFullscreen(CWindow* pWindow);
|
||||||
|
void onNewFocus(CWindow* pWindow);
|
||||||
|
void onUnmap(CWindow* pWindow);
|
||||||
|
|
||||||
|
bool good();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SP<CZwlrForeignToplevelManagerV1> resource;
|
||||||
|
bool finished = false;
|
||||||
|
CWindow* lastFocus = nullptr; // READ-ONLY
|
||||||
|
|
||||||
|
SP<CForeignToplevelHandleWlr> handleForWindow(CWindow* pWindow);
|
||||||
|
|
||||||
|
std::vector<WP<CForeignToplevelHandleWlr>> handles;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CForeignToplevelWlrProtocol : public IWaylandProtocol {
|
||||||
|
public:
|
||||||
|
CForeignToplevelWlrProtocol(const wl_interface* iface, const int& ver, const std::string& name);
|
||||||
|
|
||||||
|
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||||
|
|
||||||
|
CWindow* windowFromHandleResource(wl_resource* res);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onManagerResourceDestroy(CForeignToplevelWlrManager* mgr);
|
||||||
|
void destroyHandle(CForeignToplevelHandleWlr* handle);
|
||||||
|
|
||||||
|
//
|
||||||
|
std::vector<UP<CForeignToplevelWlrManager>> m_vManagers;
|
||||||
|
std::vector<SP<CForeignToplevelHandleWlr>> m_vHandles;
|
||||||
|
|
||||||
|
friend class CForeignToplevelWlrManager;
|
||||||
|
friend class CForeignToplevelHandleWlr;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PROTO {
|
||||||
|
inline UP<CForeignToplevelWlrProtocol> foreignToplevelWlr;
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
#include "ToplevelExport.hpp"
|
#include "ToplevelExport.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
|
#include "ForeignToplevelWlr.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -39,17 +40,12 @@ CToplevelExportProtocolManager::CToplevelExportProtocolManager() {
|
||||||
Debug::log(LOG, "ToplevelExportManager started successfully!");
|
Debug::log(LOG, "ToplevelExportManager started successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_foreign_toplevel_handle_v1* zwlrHandleFromResource(wl_resource* resource) {
|
|
||||||
// we can't assert here, but it doesnt matter.
|
|
||||||
return (wlr_foreign_toplevel_handle_v1*)wl_resource_get_user_data(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleCaptureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
|
static void handleCaptureToplevel(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, uint32_t handle) {
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromHandle(handle));
|
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromHandle(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleCaptureToplevelWithWlr(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, wl_resource* handle) {
|
static void handleCaptureToplevelWithWlr(wl_client* client, wl_resource* resource, uint32_t frame, int32_t overlay_cursor, wl_resource* handle) {
|
||||||
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, g_pCompositor->getWindowFromZWLRHandle(handle));
|
g_pProtocolManager->m_pToplevelExportProtocolManager->captureToplevel(client, resource, frame, overlay_cursor, PROTO::foreignToplevelWlr->windowFromHandleResource(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDestroy(wl_client* client, wl_resource* resource) {
|
static void handleDestroy(wl_client* client, wl_resource* resource) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "wlr-foreign-toplevel-management-unstable-v1-protocol.h"
|
|
||||||
#include "hyprland-toplevel-export-v1-protocol.h"
|
#include "hyprland-toplevel-export-v1-protocol.h"
|
||||||
#include "Screencopy.hpp"
|
#include "Screencopy.hpp"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue