mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 08:25:59 +01:00
Fixed TTY switching (#364)
This commit is contained in:
parent
ef7ee2fd0f
commit
6708f3b133
10 changed files with 70 additions and 37 deletions
|
@ -2,6 +2,16 @@
|
||||||
#include "helpers/Splashes.hpp"
|
#include "helpers/Splashes.hpp"
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
int handleCritSignal(int signo, void* data) {
|
||||||
|
Debug::log(LOG, "Hyprland received signal %d", signo);
|
||||||
|
|
||||||
|
if (signo == SIGTERM || signo == SIGINT || signo == SIGKILL) {
|
||||||
|
g_pCompositor->cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // everything went fine
|
||||||
|
}
|
||||||
|
|
||||||
CCompositor::CCompositor() {
|
CCompositor::CCompositor() {
|
||||||
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
m_szInstanceSignature = GIT_COMMIT_HASH + std::string("_") + std::to_string(time(NULL));
|
||||||
|
|
||||||
|
@ -30,6 +40,12 @@ CCompositor::CCompositor() {
|
||||||
|
|
||||||
m_sWLDisplay = wl_display_create();
|
m_sWLDisplay = wl_display_create();
|
||||||
|
|
||||||
|
m_sWLEventLoop = wl_display_get_event_loop(m_sWLDisplay);
|
||||||
|
|
||||||
|
// register crit signal handler
|
||||||
|
wl_event_loop_add_signal(m_sWLEventLoop, SIGTERM, handleCritSignal, nullptr);
|
||||||
|
//wl_event_loop_add_signal(m_sWLEventLoop, SIGINT, handleCritSignal, nullptr);
|
||||||
|
|
||||||
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
|
m_sWLRBackend = wlr_backend_autocreate(m_sWLDisplay);
|
||||||
|
|
||||||
if (!m_sWLRBackend) {
|
if (!m_sWLRBackend) {
|
||||||
|
@ -131,15 +147,12 @@ CCompositor::CCompositor() {
|
||||||
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
wlr_xdg_foreign_v2_create(m_sWLDisplay, m_sWLRForeignRegistry);
|
||||||
|
|
||||||
m_sWLRPointerGestures = wlr_pointer_gestures_v1_create(m_sWLDisplay);
|
m_sWLRPointerGestures = wlr_pointer_gestures_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
|
m_sWLRSession = wlr_backend_get_session(m_sWLRBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCompositor::~CCompositor() {
|
CCompositor::~CCompositor() {
|
||||||
cleanupExit();
|
cleanup();
|
||||||
}
|
|
||||||
|
|
||||||
void handleCritSignal(int signo) {
|
|
||||||
g_pCompositor->cleanupExit();
|
|
||||||
exit(signo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCompositor::setRandomSplash() {
|
void CCompositor::setRandomSplash() {
|
||||||
|
@ -177,12 +190,10 @@ void CCompositor::initAllSignals() {
|
||||||
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
addWLSignal(&m_sWLRVirtPtrMgr->events.new_virtual_pointer, &Events::listen_newVirtPtr, m_sWLRVirtPtrMgr, "VirtPtrMgr");
|
||||||
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
addWLSignal(&m_sWLRRenderer->events.destroy, &Events::listen_RendererDestroy, m_sWLRRenderer, "WLRRenderer");
|
||||||
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
|
addWLSignal(&m_sWLRIdleInhibitMgr->events.new_inhibitor, &Events::listen_newIdleInhibitor, m_sWLRIdleInhibitMgr, "WLRIdleInhibitMgr");
|
||||||
|
addWLSignal(&m_sWLRSession->events.active, &Events::listen_sessionActive, m_sWLRSession, "Session");
|
||||||
signal(SIGINT, handleCritSignal);
|
|
||||||
signal(SIGTERM, handleCritSignal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCompositor::cleanupExit() {
|
void CCompositor::cleanup() {
|
||||||
if (!m_sWLDisplay)
|
if (!m_sWLDisplay)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -197,8 +208,7 @@ void CCompositor::cleanupExit() {
|
||||||
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
g_pXWaylandManager->m_sWLRXWayland = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_display_destroy_clients(m_sWLDisplay);
|
wl_display_terminate(m_sWLDisplay);
|
||||||
wl_display_destroy(m_sWLDisplay);
|
|
||||||
|
|
||||||
m_sWLDisplay = nullptr;
|
m_sWLDisplay = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1334,3 +1344,10 @@ void CCompositor::updateWorkspaceWindowDecos(const int& id) {
|
||||||
w->updateWindowDecos();
|
w->updateWindowDecos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCompositor::scheduleFrameForMonitor(SMonitor* pMonitor) {
|
||||||
|
if (!m_sWLRSession->active || !m_bSessionActive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlr_output_schedule_frame(pMonitor->output);
|
||||||
|
}
|
|
@ -30,7 +30,9 @@ public:
|
||||||
|
|
||||||
// ------------------ WLR BASICS ------------------ //
|
// ------------------ WLR BASICS ------------------ //
|
||||||
wl_display* m_sWLDisplay;
|
wl_display* m_sWLDisplay;
|
||||||
|
wl_event_loop* m_sWLEventLoop;
|
||||||
wlr_backend* m_sWLRBackend;
|
wlr_backend* m_sWLRBackend;
|
||||||
|
wlr_session* m_sWLRSession;
|
||||||
wlr_renderer* m_sWLRRenderer;
|
wlr_renderer* m_sWLRRenderer;
|
||||||
wlr_allocator* m_sWLRAllocator;
|
wlr_allocator* m_sWLRAllocator;
|
||||||
wlr_compositor* m_sWLRCompositor;
|
wlr_compositor* m_sWLRCompositor;
|
||||||
|
@ -80,7 +82,7 @@ public:
|
||||||
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
|
std::vector<SLayerSurface*> m_vSurfacesFadingOut;
|
||||||
|
|
||||||
void startCompositor();
|
void startCompositor();
|
||||||
void cleanupExit();
|
void cleanup();
|
||||||
|
|
||||||
wlr_surface* m_pLastFocus = nullptr;
|
wlr_surface* m_pLastFocus = nullptr;
|
||||||
CWindow* m_pLastWindow = nullptr;
|
CWindow* m_pLastWindow = nullptr;
|
||||||
|
@ -89,6 +91,7 @@ public:
|
||||||
SSeat m_sSeat;
|
SSeat m_sSeat;
|
||||||
|
|
||||||
bool m_bReadyToProcess = false;
|
bool m_bReadyToProcess = false;
|
||||||
|
bool m_bSessionActive = true;
|
||||||
|
|
||||||
// ------------------------------------------------- //
|
// ------------------------------------------------- //
|
||||||
|
|
||||||
|
@ -142,6 +145,7 @@ public:
|
||||||
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
void setWindowFullscreen(CWindow*, bool, eFullscreenMode);
|
||||||
void moveUnmanagedX11ToWindows(CWindow*);
|
void moveUnmanagedX11ToWindows(CWindow*);
|
||||||
CWindow* getX11Parent(CWindow*);
|
CWindow* getX11Parent(CWindow*);
|
||||||
|
void scheduleFrameForMonitor(SMonitor*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initAllSignals();
|
void initAllSignals();
|
||||||
|
|
|
@ -593,7 +593,7 @@ std::string getRequestFromThread(std::string rq) {
|
||||||
// this might be a race condition
|
// this might be a race condition
|
||||||
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
|
// tested with 2 instances of `watch -n 0.1 hyprctl splash` and seems to not crash so I'll take that as a yes
|
||||||
if (!*PNOVFR)
|
if (!*PNOVFR)
|
||||||
wlr_output_schedule_frame(g_pCompositor->m_vMonitors.front()->output);
|
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_vMonitors.front().get());
|
||||||
|
|
||||||
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
while (HyprCtl::request != "" || HyprCtl::requestMade || HyprCtl::requestReady) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
|
|
@ -119,4 +119,7 @@ namespace Events {
|
||||||
LISTENER(swipeBegin);
|
LISTENER(swipeBegin);
|
||||||
LISTENER(swipeEnd);
|
LISTENER(swipeEnd);
|
||||||
LISTENER(swipeUpdate);
|
LISTENER(swipeUpdate);
|
||||||
|
|
||||||
|
// session
|
||||||
|
LISTENER(sessionActive);
|
||||||
};
|
};
|
|
@ -158,3 +158,9 @@ void Events::listener_InhibitDeactivate(wl_listener* listener, void* data) {
|
||||||
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
void Events::listener_RendererDestroy(wl_listener* listener, void* data) {
|
||||||
Debug::log(LOG, "!!Renderer destroyed!!");
|
Debug::log(LOG, "!!Renderer destroyed!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Events::listener_sessionActive(wl_listener* listener, void* data) {
|
||||||
|
Debug::log(LOG, "Session got activated!");
|
||||||
|
|
||||||
|
g_pCompositor->m_bSessionActive = true;
|
||||||
|
}
|
|
@ -166,6 +166,11 @@ void Events::listener_newOutput(wl_listener* listener, void* data) {
|
||||||
void Events::listener_monitorFrame(void* owner, void* data) {
|
void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
SMonitor* const PMONITOR = (SMonitor*)owner;
|
SMonitor* const PMONITOR = (SMonitor*)owner;
|
||||||
|
|
||||||
|
if (!g_pCompositor->m_sWLRSession->active || !g_pCompositor->m_bSessionActive) {
|
||||||
|
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
||||||
|
return; // cannot draw on session inactive (different tty)
|
||||||
|
}
|
||||||
|
|
||||||
static std::chrono::high_resolution_clock::time_point startRender = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point startRender = std::chrono::high_resolution_clock::now();
|
||||||
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point startRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
static std::chrono::high_resolution_clock::time_point endRenderOverlay = std::chrono::high_resolution_clock::now();
|
||||||
|
@ -182,6 +187,18 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
g_pDebugOverlay->frameData(PMONITOR);
|
g_pDebugOverlay->frameData(PMONITOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PMONITOR->framesToSkip > 0) {
|
||||||
|
PMONITOR->framesToSkip -= 1;
|
||||||
|
|
||||||
|
if (!PMONITOR->noFrameSchedule)
|
||||||
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
|
else {
|
||||||
|
Debug::log(LOG, "NoFrameSchedule hit for %s.", PMONITOR->szName.c_str());
|
||||||
|
}
|
||||||
|
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// checks //
|
// checks //
|
||||||
if (PMONITOR->ID == pMostHzMonitor->ID || !*PNOVFR) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
if (PMONITOR->ID == pMostHzMonitor->ID || !*PNOVFR) { // unfortunately with VFR we don't have the guarantee mostHz is going to be updated all the time, so we have to ignore that
|
||||||
g_pCompositor->sanityCheckWorkspaces();
|
g_pCompositor->sanityCheckWorkspaces();
|
||||||
|
@ -198,18 +215,6 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
}
|
}
|
||||||
// //
|
// //
|
||||||
|
|
||||||
if (PMONITOR->framesToSkip > 0) {
|
|
||||||
PMONITOR->framesToSkip -= 1;
|
|
||||||
|
|
||||||
if (!PMONITOR->noFrameSchedule)
|
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
|
||||||
else {
|
|
||||||
Debug::log(LOG, "NoFrameSchedule hit for %s.", PMONITOR->szName.c_str());
|
|
||||||
}
|
|
||||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(PMONITOR->ID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timespec now;
|
timespec now;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
|
@ -236,7 +241,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
wlr_output_rollback(PMONITOR->output);
|
wlr_output_rollback(PMONITOR->output);
|
||||||
|
|
||||||
if (*PDAMAGEBLINK || *PNOVFR)
|
if (*PDAMAGEBLINK || *PNOVFR)
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -326,7 +331,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
wlr_output_commit(PMONITOR->output);
|
wlr_output_commit(PMONITOR->output);
|
||||||
|
|
||||||
if (*PDAMAGEBLINK || *PNOVFR)
|
if (*PDAMAGEBLINK || *PNOVFR)
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
|
|
||||||
if (*PDEBUGOVERLAY == 1) {
|
if (*PDEBUGOVERLAY == 1) {
|
||||||
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
const float µs = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - startRender).count() / 1000.f;
|
||||||
|
@ -360,8 +365,7 @@ void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||||
|
|
||||||
if (!BACKUPMON) {
|
if (!BACKUPMON) {
|
||||||
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
Debug::log(CRIT, "No monitors! Unplugged last! Exiting.");
|
||||||
g_pCompositor->cleanupExit();
|
g_pCompositor->cleanup();
|
||||||
exit(1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ int main(int argc, char** argv) {
|
||||||
// If we are here it means we got yote.
|
// If we are here it means we got yote.
|
||||||
Debug::log(LOG, "Hyprland reached the end.");
|
Debug::log(LOG, "Hyprland reached the end.");
|
||||||
|
|
||||||
g_pCompositor->cleanupExit();
|
g_pCompositor->cleanup();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,7 @@ void CAnimationManager::tick() {
|
||||||
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
g_pXWaylandManager->setWindowSize(PWINDOW, PWINDOW->m_vRealSize.goalv());
|
||||||
|
|
||||||
// manually schedule a frame
|
// manually schedule a frame
|
||||||
wlr_output_schedule_frame(PMONITOR->output);
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,11 +140,11 @@ bool CKeybindManager::handleVT(xkb_keysym_t keysym) {
|
||||||
if (PSESSION) {
|
if (PSESSION) {
|
||||||
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
const int TTY = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||||
wlr_session_change_vt(PSESSION, TTY);
|
wlr_session_change_vt(PSESSION, TTY);
|
||||||
|
g_pCompositor->m_bSessionActive = false;
|
||||||
|
|
||||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
g_pHyprOpenGL->destroyMonitorResources(m.get()); // mark resources as unusable anymore
|
|
||||||
m->noFrameSchedule = true;
|
m->noFrameSchedule = true;
|
||||||
m->framesToSkip = 2;
|
m->framesToSkip = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Switched to VT %i, destroyed all render data, frames to skip for each: 2", TTY);
|
Debug::log(LOG, "Switched to VT %i, destroyed all render data, frames to skip for each: 2", TTY);
|
||||||
|
@ -812,8 +812,7 @@ void CKeybindManager::workspaceOpt(std::string args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::exitHyprland(std::string argz) {
|
void CKeybindManager::exitHyprland(std::string argz) {
|
||||||
g_pCompositor->cleanupExit();
|
g_pCompositor->cleanup();
|
||||||
exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
void CKeybindManager::moveCurrentWorkspaceToMonitor(std::string args) {
|
||||||
|
|
|
@ -599,7 +599,7 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) {
|
||||||
|
|
||||||
// schedule frame events
|
// schedule frame events
|
||||||
if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
|
if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
|
||||||
wlr_output_schedule_frame(g_pCompositor->getMonitorFromVector(Vector2D(x, y))->output);
|
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pixman_region32_not_empty(&damageBox)) {
|
if (!pixman_region32_not_empty(&damageBox)) {
|
||||||
|
|
Loading…
Reference in a new issue