mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-25 22:05:59 +01:00
XWayland and moved managers
This commit is contained in:
parent
854c827911
commit
a9773bd91a
13 changed files with 245 additions and 31 deletions
|
@ -76,17 +76,20 @@ void CCompositor::startCompositor() {
|
|||
// Init all the managers BEFORE we start with the wayland server so that ALL of the stuff is initialized
|
||||
// properly and we dont get any bad mem reads.
|
||||
//
|
||||
Debug::log(LOG, "Creating the config manager!");
|
||||
Debug::log(LOG, "Creating the ConfigManager!");
|
||||
g_pConfigManager = std::make_unique<CConfigManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the ManagerThread!");
|
||||
g_pManagerThread = std::make_unique<CManagerThread>();
|
||||
Debug::log(LOG, "Creating the ThreadManager!");
|
||||
g_pThreadManager = std::make_unique<CThreadManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the InputManager!");
|
||||
g_pInputManager = std::make_unique<CInputManager>();
|
||||
|
||||
Debug::log(LOG, "Creating the HyprRenderer!");
|
||||
g_pHyprRenderer = std::make_unique<CHyprRenderer>();
|
||||
|
||||
Debug::log(LOG, "Creating the XWaylandManager!");
|
||||
g_pXWaylandManager = std::make_unique<CHyprXWaylandManager>();
|
||||
//
|
||||
//
|
||||
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
#include "debug/Log.hpp"
|
||||
#include "events/Events.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "ManagerThread.hpp"
|
||||
#include "input/InputManager.hpp"
|
||||
#include "managers/ThreadManager.hpp"
|
||||
#include "managers/XWaylandManager.hpp"
|
||||
#include "managers/InputManager.hpp"
|
||||
#include "helpers/Monitor.hpp"
|
||||
#include "Window.hpp"
|
||||
#include "render/Renderer.hpp"
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "defines.hpp"
|
||||
#include <thread>
|
||||
#include "Compositor.hpp"
|
||||
|
||||
class CManagerThread {
|
||||
public:
|
||||
CManagerThread();
|
||||
~CManagerThread();
|
||||
|
||||
private:
|
||||
|
||||
void handle();
|
||||
|
||||
std::thread* m_tMainThread;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CManagerThread> g_pManagerThread;
|
|
@ -37,4 +37,12 @@ public:
|
|||
bool m_bIsFloating = false;
|
||||
bool m_bIsFullscreen = false;
|
||||
uint64_t m_iMonitorID = -1;
|
||||
|
||||
// XWayland stuff
|
||||
bool m_bIsX11 = false;
|
||||
uint64_t m_iX11Type = 0;
|
||||
DYNLISTENER(activateX11);
|
||||
DYNLISTENER(configureX11);
|
||||
//
|
||||
|
||||
};
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "../Compositor.hpp"
|
||||
#include "../helpers/WLClasses.hpp"
|
||||
#include "../input/InputManager.hpp"
|
||||
#include "../managers/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
void Events::listener_activate(wl_listener* listener, void* data) {
|
||||
|
@ -157,7 +157,7 @@ void Events::listener_mapWindow(wl_listener* listener, void* data) {
|
|||
PWINDOW->m_iMonitorID = PMONITOR->ID;
|
||||
|
||||
// test
|
||||
wlr_xdg_toplevel_set_size(PWINDOW->m_uSurface.xdg->toplevel, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
|
||||
g_pXWaylandManager->setWindowSize(PWINDOW, PMONITOR->vecSize);
|
||||
|
||||
Debug::log(LOG, "Map request dispatched.");
|
||||
}
|
||||
|
@ -198,6 +198,68 @@ void Events::listener_keyboardDestroy(wl_listener* listener, void* data) {
|
|||
|
||||
}
|
||||
|
||||
void Events::listener_activateX11(wl_listener* listener, void* data) {
|
||||
CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_mapWindow);
|
||||
|
||||
if (PWINDOW->m_iX11Type == 1 /* Managed */) {
|
||||
wlr_xwayland_surface_activate(PWINDOW->m_uSurface.xwayland, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Events::listener_configureX11(wl_listener* listener, void* data) {
|
||||
CWindow* PWINDOW = wl_container_of(listener, PWINDOW, listen_mapWindow);
|
||||
|
||||
const auto E = (wlr_xwayland_surface_configure_event*)data;
|
||||
|
||||
// TODO: ignore if tiled?
|
||||
wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
|
||||
}
|
||||
|
||||
void Events::listener_readyXWayland(wl_listener* listener, void* data) {
|
||||
const auto XCBCONNECTION = xcb_connect(g_pXWaylandManager->m_sWLRXWayland->display_name, NULL);
|
||||
const auto ERR = xcb_connection_has_error(XCBCONNECTION);
|
||||
if (ERR) {
|
||||
Debug::log(LogLevel::ERR, "xcb_connection_has_error failed with %i", ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: atoms
|
||||
|
||||
wlr_xwayland_set_seat(g_pXWaylandManager->m_sWLRXWayland, g_pCompositor->m_sWLRSeat);
|
||||
|
||||
const auto XCURSOR = wlr_xcursor_manager_get_xcursor(g_pCompositor->m_sWLRXCursorMgr, "left_ptr", 1);
|
||||
if (XCURSOR) {
|
||||
wlr_xwayland_set_cursor(g_pXWaylandManager->m_sWLRXWayland, XCURSOR->images[0]->buffer, XCURSOR->images[0]->width * 4, XCURSOR->images[0]->width, XCURSOR->images[0]->height, XCURSOR->images[0]->hotspot_x, XCURSOR->images[0]->hotspot_y);
|
||||
}
|
||||
|
||||
xcb_disconnect(XCBCONNECTION);
|
||||
}
|
||||
|
||||
void Events::listener_surfaceXWayland(wl_listener* listener, void* data) {
|
||||
|
||||
}
|
||||
|
||||
void Events::listener_createX11(wl_listener* listener, void* data) {
|
||||
const auto XWSURFACE = (wlr_xwayland_surface*)data;
|
||||
|
||||
g_pCompositor->m_vWindows.push_back(CWindow());
|
||||
const auto PNEWWINDOW = &g_pCompositor->m_vWindows.back();
|
||||
|
||||
PNEWWINDOW->m_uSurface.xwayland = XWSURFACE;
|
||||
PNEWWINDOW->m_iX11Type = XWSURFACE->override_redirect ? 2 : 1;
|
||||
PNEWWINDOW->m_bIsX11 = true;
|
||||
|
||||
wl_signal_add(&XWSURFACE->events.map, &PNEWWINDOW->listen_mapWindow);
|
||||
wl_signal_add(&XWSURFACE->events.unmap, &PNEWWINDOW->listen_unmapWindow);
|
||||
wl_signal_add(&XWSURFACE->events.request_activate, &PNEWWINDOW->listen_activateX11);
|
||||
wl_signal_add(&XWSURFACE->events.request_configure, &PNEWWINDOW->listen_configureX11);
|
||||
wl_signal_add(&XWSURFACE->events.set_title, &PNEWWINDOW->listen_setTitleWindow);
|
||||
wl_signal_add(&XWSURFACE->events.destroy, &PNEWWINDOW->listen_destroyWindow);
|
||||
wl_signal_add(&XWSURFACE->events.request_fullscreen, &PNEWWINDOW->listen_fullscreenWindow);
|
||||
|
||||
Debug::log(LOG, "New XWayland Surface created.");
|
||||
}
|
||||
|
||||
void Events::listener_keyboardKey(wl_listener* listener, void* data) {
|
||||
g_pInputManager->onKeyboardKey((wlr_event_keyboard_key*)data);
|
||||
}
|
||||
|
|
|
@ -2,25 +2,32 @@
|
|||
#include "../defines.hpp"
|
||||
|
||||
namespace Events {
|
||||
LISTENER(activate);
|
||||
// Monitor events
|
||||
LISTENER(change);
|
||||
LISTENER(newOutput);
|
||||
|
||||
// Layer events
|
||||
LISTENER(newLayerSurface);
|
||||
LISTENER(destroyLayerSurface);
|
||||
LISTENER(mapLayerSurface);
|
||||
LISTENER(unmapLayerSurface);
|
||||
LISTENER(commitLayerSurface);
|
||||
|
||||
// Surface XDG (window)
|
||||
LISTENER(newXDGSurface);
|
||||
|
||||
// Window events
|
||||
LISTENER(commitWindow);
|
||||
LISTENER(mapWindow);
|
||||
LISTENER(unmapWindow);
|
||||
LISTENER(destroyWindow);
|
||||
LISTENER(setTitleWindow);
|
||||
LISTENER(fullscreenWindow);
|
||||
LISTENER(activateX11);
|
||||
LISTENER(configureX11);
|
||||
LISTENER(createX11);
|
||||
|
||||
// Input events
|
||||
LISTENER(mouseMove);
|
||||
LISTENER(mouseMoveAbsolute);
|
||||
LISTENER(mouseButton);
|
||||
|
@ -33,13 +40,21 @@ namespace Events {
|
|||
LISTENER(keyboardMod);
|
||||
LISTENER(keyboardDestroy);
|
||||
|
||||
// Various
|
||||
LISTENER(requestMouse);
|
||||
LISTENER(requestSetSel);
|
||||
LISTENER(requestSetPrimarySel);
|
||||
LISTENER(activate);
|
||||
|
||||
// outputMgr
|
||||
LISTENER(outputMgrApply);
|
||||
LISTENER(outputMgrTest);
|
||||
|
||||
// Monitor part 2 the sequel
|
||||
LISTENER(monitorFrame);
|
||||
LISTENER(monitorDestroy);
|
||||
|
||||
// XWayland
|
||||
LISTENER(readyXWayland);
|
||||
LISTENER(surfaceXWayland);
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
#include "ManagerThread.hpp"
|
||||
#include "ThreadManager.hpp"
|
||||
|
||||
CManagerThread::CManagerThread() {
|
||||
CThreadManager::CThreadManager() {
|
||||
m_tMainThread = new std::thread([&]() {
|
||||
// Call the handle method.
|
||||
this->handle();
|
||||
|
@ -9,11 +9,11 @@ CManagerThread::CManagerThread() {
|
|||
m_tMainThread->detach(); // detach and continue.
|
||||
}
|
||||
|
||||
CManagerThread::~CManagerThread() {
|
||||
CThreadManager::~CThreadManager() {
|
||||
//
|
||||
}
|
||||
|
||||
void CManagerThread::handle() {
|
||||
void CThreadManager::handle() {
|
||||
|
||||
g_pConfigManager->init();
|
||||
|
19
src/managers/ThreadManager.hpp
Normal file
19
src/managers/ThreadManager.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include <thread>
|
||||
#include "../Compositor.hpp"
|
||||
|
||||
class CThreadManager {
|
||||
public:
|
||||
CThreadManager();
|
||||
~CThreadManager();
|
||||
|
||||
private:
|
||||
|
||||
void handle();
|
||||
|
||||
std::thread* m_tMainThread;
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CThreadManager> g_pThreadManager;
|
84
src/managers/XWaylandManager.cpp
Normal file
84
src/managers/XWaylandManager.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "XWaylandManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "../events/Events.hpp"
|
||||
|
||||
CHyprXWaylandManager::CHyprXWaylandManager() {
|
||||
m_sWLRXWayland = wlr_xwayland_create(g_pCompositor->m_sWLDisplay, g_pCompositor->m_sWLRCompositor, 1);
|
||||
|
||||
if (!m_sWLRXWayland) {
|
||||
Debug::log(ERR, "Couldn't start up the XWaylandManager because wlr_xwayland_create returned a nullptr!");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_signal_add(&m_sWLRXWayland->events.ready, &Events::listen_readyXWayland);
|
||||
wl_signal_add(&m_sWLRXWayland->events.new_surface, &Events::listen_surfaceXWayland);
|
||||
|
||||
setenv("DISPLAY", m_sWLRXWayland->display_name, 1);
|
||||
|
||||
Debug::log(LOG, "CHyprXWaylandManager started on display %s", m_sWLRXWayland->display_name);
|
||||
}
|
||||
|
||||
CHyprXWaylandManager::~CHyprXWaylandManager() {
|
||||
|
||||
}
|
||||
|
||||
wlr_surface* CHyprXWaylandManager::getWindowSurface(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsX11)
|
||||
return pWindow->m_uSurface.xwayland->surface;
|
||||
|
||||
return pWindow->m_uSurface.xdg->surface;
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::activateSurface(wlr_surface* pSurface, bool activate) {
|
||||
if (wlr_surface_is_xdg_surface(pSurface))
|
||||
wlr_xdg_toplevel_set_activated(wlr_xdg_surface_from_wlr_surface(pSurface)->toplevel, activate);
|
||||
|
||||
else if (wlr_surface_is_xwayland_surface(pSurface))
|
||||
wlr_xwayland_surface_activate(wlr_xwayland_surface_from_wlr_surface(pSurface), activate);
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::getGeometryForWindow(CWindow* pWindow, wlr_box* pbox) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
pbox->x = pWindow->m_uSurface.xwayland->x;
|
||||
pbox->y = pWindow->m_uSurface.xwayland->y;
|
||||
pbox->width = pWindow->m_uSurface.xwayland->width;
|
||||
pbox->height = pWindow->m_uSurface.xwayland->height;
|
||||
} else {
|
||||
wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, pbox);
|
||||
}
|
||||
}
|
||||
|
||||
std::string CHyprXWaylandManager::getTitle(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsX11)
|
||||
return pWindow->m_uSurface.xwayland->title;
|
||||
|
||||
return pWindow->m_uSurface.xdg->toplevel->title;
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::sendCloseWindow(CWindow* pWindow) {
|
||||
if (pWindow->m_bIsX11) {
|
||||
wlr_xwayland_surface_close(pWindow->m_uSurface.xwayland);
|
||||
} else {
|
||||
wlr_xdg_toplevel_send_close(pWindow->m_uSurface.xdg->toplevel);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, const Vector2D& size) {
|
||||
if (pWindow->m_bIsX11)
|
||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vPosition.x, pWindow->m_vPosition.y, size.x, size.y);
|
||||
|
||||
else
|
||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
|
||||
}
|
||||
|
||||
void CHyprXWaylandManager::setWindowStyleTiled(CWindow* pWindow, uint32_t edgez) {
|
||||
if (!pWindow->m_bIsX11)
|
||||
wlr_xdg_toplevel_set_tiled(pWindow->m_uSurface.xdg->toplevel, edgez);
|
||||
}
|
||||
|
||||
wlr_surface* CHyprXWaylandManager::surfaceAt(CWindow* pWindow, const Vector2D& client, Vector2D& server) {
|
||||
if (pWindow->m_bIsX11)
|
||||
return wlr_surface_surface_at(pWindow->m_uSurface.xwayland->surface, client.x, client.y, &server.x, &server.y);
|
||||
|
||||
return wlr_xdg_surface_surface_at(pWindow->m_uSurface.xdg, client.x, client.y, &server.x, &server.y);
|
||||
}
|
23
src/managers/XWaylandManager.hpp
Normal file
23
src/managers/XWaylandManager.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../Window.hpp"
|
||||
|
||||
class CHyprXWaylandManager {
|
||||
public:
|
||||
CHyprXWaylandManager();
|
||||
~CHyprXWaylandManager();
|
||||
|
||||
wlr_xwayland* m_sWLRXWayland;
|
||||
|
||||
wlr_surface* getWindowSurface(CWindow*);
|
||||
void activateSurface(wlr_surface*, bool);
|
||||
void getGeometryForWindow(CWindow*, wlr_box*);
|
||||
std::string getTitle(CWindow*);
|
||||
void sendCloseWindow(CWindow*);
|
||||
void setWindowSize(CWindow*, const Vector2D&);
|
||||
void setWindowStyleTiled(CWindow*, uint32_t);
|
||||
wlr_surface* surfaceAt(CWindow*, const Vector2D&, Vector2D&);
|
||||
};
|
||||
|
||||
inline std::unique_ptr<CHyprXWaylandManager> g_pXWaylandManager;
|
|
@ -40,6 +40,9 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
|||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
|
||||
if (w.m_bIsX11)
|
||||
continue;
|
||||
|
||||
const wlr_box geom = { w.m_vPosition.x, w.m_vPosition.y, w.m_vSize.x, w.m_vSize.y };
|
||||
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, PMONITOR->output, &geom))
|
||||
|
@ -54,4 +57,19 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
|
|||
wlr_surface_for_each_surface(w.m_uSurface.xdg->surface, renderSurface, &renderdata);
|
||||
wlr_xdg_surface_for_each_popup_surface(w.m_uSurface.xdg, renderSurface, &renderdata);
|
||||
}
|
||||
|
||||
for (auto& w : g_pCompositor->m_vWindows) {
|
||||
|
||||
if (!w.m_bIsX11)
|
||||
continue;
|
||||
|
||||
wlr_box geometry = { w.m_uSurface.xwayland->x, w.m_uSurface.xwayland->y, w.m_uSurface.xwayland->width, w.m_uSurface.xwayland->height };
|
||||
|
||||
if (!wlr_output_layout_intersects(g_pCompositor->m_sWLROutputLayout, PMONITOR->output, &geometry))
|
||||
continue;
|
||||
|
||||
SRenderData renderdata = {PMONITOR->output, time, w.m_vSize.x, w.m_vSize.y};
|
||||
|
||||
wlr_surface_for_each_surface(w.m_uSurface.xwayland->surface, renderSurface, &renderdata);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue