2022-03-21 15:17:04 +01:00
|
|
|
#include "../Compositor.hpp"
|
|
|
|
#include "../helpers/WLClasses.hpp"
|
2022-06-09 12:46:55 +02:00
|
|
|
#include "../managers/input/InputManager.hpp"
|
2022-03-21 15:17:04 +01:00
|
|
|
#include "../render/Renderer.hpp"
|
|
|
|
#include "Events.hpp"
|
2022-04-21 22:00:03 +02:00
|
|
|
#include "../debug/HyprCtl.hpp"
|
2022-03-21 15:17:04 +01:00
|
|
|
|
|
|
|
// --------------------------------------------------------- //
|
|
|
|
// __ __ ____ _ _ _____ _______ ____ _____ _____ //
|
|
|
|
// | \/ |/ __ \| \ | |_ _|__ __/ __ \| __ \ / ____| //
|
|
|
|
// | \ / | | | | \| | | | | | | | | | |__) | (___ //
|
|
|
|
// | |\/| | | | | . ` | | | | | | | | | _ / \___ \ //
|
|
|
|
// | | | | |__| | |\ |_| |_ | | | |__| | | \ \ ____) | //
|
|
|
|
// |_| |_|\____/|_| \_|_____| |_| \____/|_| \_\_____/ //
|
|
|
|
// //
|
|
|
|
// --------------------------------------------------------- //
|
|
|
|
|
2022-12-22 13:15:00 +01:00
|
|
|
void Events::listener_change(wl_listener* listener, void* data) {
|
2022-03-21 15:17:04 +01:00
|
|
|
// layout got changed, let's update monitors.
|
|
|
|
const auto CONFIG = wlr_output_configuration_v1_create();
|
|
|
|
|
2023-04-12 21:18:55 +02:00
|
|
|
if (!CONFIG)
|
|
|
|
return;
|
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
2023-03-15 18:01:20 +01:00
|
|
|
if (!m->output)
|
|
|
|
continue;
|
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
const auto CONFIGHEAD = wlr_output_configuration_head_v1_create(CONFIG, m->output);
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2023-06-23 21:14:04 +02:00
|
|
|
wlr_box BOX;
|
2022-06-30 15:44:26 +02:00
|
|
|
wlr_output_layout_get_box(g_pCompositor->m_sWLROutputLayout, m->output, &BOX);
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
//m->vecSize.x = BOX.width;
|
2022-12-16 18:17:31 +01:00
|
|
|
// m->vecSize.y = BOX.height;
|
2022-06-30 15:44:26 +02:00
|
|
|
m->vecPosition.x = BOX.x;
|
|
|
|
m->vecPosition.y = BOX.y;
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2022-06-30 15:44:26 +02:00
|
|
|
CONFIGHEAD->state.enabled = m->output->enabled;
|
2022-12-16 18:17:31 +01:00
|
|
|
CONFIGHEAD->state.mode = m->output->current_mode;
|
2023-09-10 14:14:27 +02:00
|
|
|
if (!m->output->current_mode) {
|
|
|
|
CONFIGHEAD->state.custom_mode = {
|
|
|
|
m->output->width,
|
|
|
|
m->output->height,
|
|
|
|
m->output->refresh,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
CONFIGHEAD->state.x = m->vecPosition.x;
|
|
|
|
CONFIGHEAD->state.y = m->vecPosition.y;
|
|
|
|
CONFIGHEAD->state.transform = m->transform;
|
|
|
|
CONFIGHEAD->state.scale = m->scale;
|
|
|
|
CONFIGHEAD->state.adaptive_sync_enabled = m->vrrActive;
|
2022-03-21 15:17:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
wlr_output_manager_v1_set_configuration(g_pCompositor->m_sWLROutputMgr, CONFIG);
|
|
|
|
}
|
|
|
|
|
2022-06-17 20:31:15 +02:00
|
|
|
void Events::listener_newOutput(wl_listener* listener, void* data) {
|
2023-03-30 00:44:25 +02:00
|
|
|
// new monitor added, let's accommodate for that.
|
2022-06-17 20:31:15 +02:00
|
|
|
const auto OUTPUT = (wlr_output*)data;
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2023-01-28 13:26:33 +01:00
|
|
|
// for warping the cursor on launch
|
|
|
|
static bool firstLaunch = true;
|
|
|
|
|
2022-06-17 20:31:15 +02:00
|
|
|
if (!OUTPUT->name) {
|
2022-05-29 20:15:34 +02:00
|
|
|
Debug::log(ERR, "New monitor has no name?? Ignoring");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-01 22:03:56 +02:00
|
|
|
if (g_pCompositor->m_bUnsafeState)
|
2022-08-10 21:54:09 +02:00
|
|
|
Debug::log(WARN, "Recovering from an unsafe state. May you be lucky.");
|
2022-05-29 20:15:34 +02:00
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
// add it to real
|
2022-08-10 21:54:09 +02:00
|
|
|
std::shared_ptr<CMonitor>* PNEWMONITORWRAP = nullptr;
|
|
|
|
|
2023-09-01 22:03:56 +02:00
|
|
|
PNEWMONITORWRAP = &g_pCompositor->m_vRealMonitors.emplace_back(std::make_shared<CMonitor>());
|
2022-08-10 21:54:09 +02:00
|
|
|
|
2023-09-01 22:03:56 +02:00
|
|
|
(*PNEWMONITORWRAP)->ID = g_pCompositor->getNextAvailableMonitorID(OUTPUT->name);
|
2022-08-10 21:54:09 +02:00
|
|
|
|
|
|
|
const auto PNEWMONITOR = PNEWMONITORWRAP->get();
|
2022-08-03 16:19:00 +02:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
PNEWMONITOR->output = OUTPUT;
|
2022-07-27 12:32:00 +02:00
|
|
|
PNEWMONITOR->m_pThisWrap = PNEWMONITORWRAP;
|
2022-06-21 22:13:13 +02:00
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
PNEWMONITOR->onConnect(false);
|
2022-04-20 19:36:05 +02:00
|
|
|
|
2022-12-22 13:15:00 +01:00
|
|
|
if ((!g_pHyprRenderer->m_pMostHzMonitor || PNEWMONITOR->refreshRate > g_pHyprRenderer->m_pMostHzMonitor->refreshRate) && PNEWMONITOR->m_bEnabled)
|
|
|
|
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
|
2022-07-12 10:02:12 +02:00
|
|
|
|
2023-09-24 19:04:38 +02:00
|
|
|
// wlroots will instantly call this handler before we get a return to the wlr_output* in CCompositor::enterUnsafeState
|
|
|
|
const bool PROBABLYFALLBACK = (g_pCompositor->m_bUnsafeState && !g_pCompositor->m_pUnsafeOutput) || OUTPUT == g_pCompositor->m_pUnsafeOutput;
|
2023-09-01 22:03:56 +02:00
|
|
|
|
2023-09-24 19:04:38 +02:00
|
|
|
// ready to process if we have a real monitor
|
|
|
|
if (PNEWMONITOR->m_bEnabled && !PROBABLYFALLBACK) {
|
|
|
|
// leave unsafe state
|
2023-09-01 22:03:56 +02:00
|
|
|
if (g_pCompositor->m_bUnsafeState) {
|
|
|
|
// recover workspaces
|
2023-09-24 19:04:38 +02:00
|
|
|
std::vector<CWorkspace*> wsp;
|
2023-09-01 22:03:56 +02:00
|
|
|
for (auto& ws : g_pCompositor->m_vWorkspaces) {
|
2023-09-24 19:04:38 +02:00
|
|
|
wsp.push_back(ws.get());
|
|
|
|
}
|
|
|
|
for (auto& ws : wsp) {
|
|
|
|
// because this can realloc the vec
|
|
|
|
g_pCompositor->moveWorkspaceToMonitor(ws, PNEWMONITOR);
|
2023-09-01 22:03:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
g_pHyprRenderer->m_pMostHzMonitor = PNEWMONITOR;
|
|
|
|
|
2023-09-11 11:09:34 +02:00
|
|
|
const auto POS = PNEWMONITOR->middle();
|
2023-09-01 22:03:56 +02:00
|
|
|
if (g_pCompositor->m_sSeat.mouse)
|
|
|
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, POS.x, POS.y);
|
|
|
|
}
|
|
|
|
|
2022-08-10 13:44:04 +02:00
|
|
|
g_pCompositor->m_bReadyToProcess = true;
|
2022-08-10 21:54:09 +02:00
|
|
|
}
|
2022-11-19 14:01:32 +01:00
|
|
|
|
|
|
|
g_pConfigManager->m_bWantsMonitorReload = true;
|
|
|
|
g_pCompositor->scheduleFrameForMonitor(PNEWMONITOR);
|
2023-01-28 13:26:33 +01:00
|
|
|
|
|
|
|
if (firstLaunch) {
|
2023-01-28 19:28:38 +01:00
|
|
|
firstLaunch = false;
|
2023-09-11 11:09:34 +02:00
|
|
|
const auto POS = PNEWMONITOR->middle();
|
2023-01-28 19:28:38 +01:00
|
|
|
if (g_pCompositor->m_sSeat.mouse)
|
|
|
|
wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, POS.x, POS.y);
|
2023-03-21 18:46:26 +01:00
|
|
|
} else {
|
|
|
|
for (auto& w : g_pCompositor->m_vWindows) {
|
|
|
|
if (w->m_iMonitorID == PNEWMONITOR->ID) {
|
|
|
|
w->m_iLastSurfaceMonitorID = -1;
|
|
|
|
w->updateSurfaceOutputs();
|
|
|
|
}
|
|
|
|
}
|
2023-01-28 13:26:33 +01:00
|
|
|
}
|
2022-03-21 15:17:04 +01:00
|
|
|
}
|
|
|
|
|
2022-06-17 20:31:15 +02:00
|
|
|
void Events::listener_monitorFrame(void* owner, void* data) {
|
2022-07-27 12:32:00 +02:00
|
|
|
CMonitor* const PMONITOR = (CMonitor*)owner;
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2022-08-10 21:54:09 +02:00
|
|
|
if ((g_pCompositor->m_sWLRSession && !g_pCompositor->m_sWLRSession->active) || !g_pCompositor->m_bSessionActive || g_pCompositor->m_bUnsafeState) {
|
2022-07-13 18:18:23 +02:00
|
|
|
Debug::log(WARN, "Attempted to render frame on inactive session!");
|
2023-03-15 16:11:41 +01:00
|
|
|
|
2023-09-24 19:04:38 +02:00
|
|
|
if (g_pCompositor->m_bUnsafeState && PMONITOR->output != g_pCompositor->m_pUnsafeOutput) {
|
|
|
|
// restore from unsafe state
|
|
|
|
g_pCompositor->leaveUnsafeState();
|
|
|
|
}
|
2023-03-15 16:11:41 +01:00
|
|
|
|
2022-07-13 18:18:23 +02:00
|
|
|
return; // cannot draw on session inactive (different tty)
|
|
|
|
}
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
if (!PMONITOR->m_bEnabled)
|
|
|
|
return;
|
2022-07-13 18:18:23 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
static auto* const PENABLERAT = &g_pConfigManager->getConfigValuePtr("misc:render_ahead_of_time")->intValue;
|
|
|
|
static auto* const PRATSAFE = &g_pConfigManager->getConfigValuePtr("misc:render_ahead_safezone")->intValue;
|
2022-05-28 17:32:19 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
PMONITOR->lastPresentationTimer.reset();
|
2022-06-29 11:44:00 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
if (*PENABLERAT) {
|
|
|
|
if (!PMONITOR->RATScheduled) {
|
|
|
|
// render
|
|
|
|
g_pHyprRenderer->renderMonitor(PMONITOR);
|
2022-07-13 18:18:23 +02:00
|
|
|
}
|
2022-07-31 16:54:36 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
PMONITOR->RATScheduled = false;
|
2022-07-13 18:18:23 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR);
|
2022-04-12 20:02:57 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
if (max + *PRATSAFE > 1000.0 / PMONITOR->refreshRate)
|
2022-11-05 13:50:47 +01:00
|
|
|
return;
|
2022-05-06 16:06:21 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis();
|
2022-09-25 20:07:48 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
PMONITOR->RATScheduled = true;
|
2022-04-14 16:43:29 +02:00
|
|
|
|
2023-03-24 20:23:16 +01:00
|
|
|
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
|
|
|
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2023-03-24 23:24:12 +01:00
|
|
|
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
2023-03-24 20:23:16 +01:00
|
|
|
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
|
|
else
|
|
|
|
wl_event_source_timer_update(PMONITOR->renderTimer, TIMETOSLEEP);
|
2022-09-13 15:25:42 +02:00
|
|
|
} else {
|
2023-03-24 20:23:16 +01:00
|
|
|
g_pHyprRenderer->renderMonitor(PMONITOR);
|
2022-05-28 17:40:57 +02:00
|
|
|
}
|
2022-03-21 15:17:04 +01:00
|
|
|
}
|
|
|
|
|
2022-06-17 20:31:15 +02:00
|
|
|
void Events::listener_monitorDestroy(void* owner, void* data) {
|
|
|
|
const auto OUTPUT = (wlr_output*)data;
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2022-12-16 18:17:31 +01:00
|
|
|
CMonitor* pMonitor = nullptr;
|
2022-03-21 15:17:04 +01:00
|
|
|
|
2022-11-19 14:14:55 +01:00
|
|
|
for (auto& m : g_pCompositor->m_vRealMonitors) {
|
|
|
|
if (m->output == OUTPUT) {
|
2022-06-30 15:44:26 +02:00
|
|
|
pMonitor = m.get();
|
2022-03-21 15:17:04 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pMonitor)
|
|
|
|
return;
|
|
|
|
|
2023-09-06 12:51:36 +02:00
|
|
|
Debug::log(LOG, "Destroy called for monitor {}", pMonitor->output->name);
|
2022-11-19 14:01:32 +01:00
|
|
|
|
2022-07-27 12:32:00 +02:00
|
|
|
pMonitor->onDisconnect();
|
2022-05-31 17:17:44 +02:00
|
|
|
|
2023-03-15 16:11:41 +01:00
|
|
|
pMonitor->output = nullptr;
|
|
|
|
pMonitor->m_bRenderingInitPassed = false;
|
|
|
|
|
2023-09-24 19:04:38 +02:00
|
|
|
if (g_pCompositor->m_pUnsafeOutput == OUTPUT)
|
|
|
|
g_pCompositor->m_pUnsafeOutput = nullptr;
|
|
|
|
|
2023-09-06 21:45:37 +02:00
|
|
|
Debug::log(LOG, "Removing monitor {} from realMonitors", pMonitor->szName);
|
2022-11-19 14:01:32 +01:00
|
|
|
|
2023-09-01 22:03:56 +02:00
|
|
|
std::erase_if(g_pCompositor->m_vRealMonitors, [&](std::shared_ptr<CMonitor>& el) { return el.get() == pMonitor; });
|
2022-03-21 15:17:04 +01:00
|
|
|
}
|
2022-11-19 17:28:04 +01:00
|
|
|
|
|
|
|
void Events::listener_monitorStateRequest(void* owner, void* data) {
|
|
|
|
const auto PMONITOR = (CMonitor*)owner;
|
2022-12-16 18:17:31 +01:00
|
|
|
const auto E = (wlr_output_event_request_state*)data;
|
2022-11-19 17:28:04 +01:00
|
|
|
|
|
|
|
wlr_output_commit_state(PMONITOR->output, E->state);
|
|
|
|
}
|
2023-04-07 17:31:51 +02:00
|
|
|
|
|
|
|
void Events::listener_monitorDamage(void* owner, void* data) {
|
|
|
|
const auto PMONITOR = (CMonitor*)owner;
|
|
|
|
const auto E = (wlr_output_event_damage*)data;
|
|
|
|
|
|
|
|
PMONITOR->addDamage(E->damage);
|
|
|
|
}
|
2023-04-07 18:25:56 +02:00
|
|
|
|
|
|
|
void Events::listener_monitorNeedsFrame(void* owner, void* data) {
|
|
|
|
const auto PMONITOR = (CMonitor*)owner;
|
|
|
|
|
|
|
|
g_pCompositor->scheduleFrameForMonitor(PMONITOR);
|
|
|
|
}
|
2023-04-12 22:40:51 +02:00
|
|
|
|
|
|
|
void Events::listener_monitorCommit(void* owner, void* data) {
|
|
|
|
const auto PMONITOR = (CMonitor*)owner;
|
|
|
|
|
|
|
|
const auto E = (wlr_output_event_commit*)data;
|
|
|
|
|
2023-07-20 12:42:25 +02:00
|
|
|
if (E->committed & WLR_OUTPUT_STATE_BUFFER) {
|
2023-07-12 00:30:42 +02:00
|
|
|
g_pProtocolManager->m_pScreencopyProtocolManager->onOutputCommit(PMONITOR, E);
|
2023-07-20 12:42:25 +02:00
|
|
|
g_pProtocolManager->m_pToplevelExportProtocolManager->onOutputCommit(PMONITOR, E);
|
|
|
|
}
|
2023-06-23 21:14:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Events::listener_monitorBind(void* owner, void* data) {
|
2023-07-18 15:30:28 +02:00
|
|
|
;
|
2023-04-12 22:40:51 +02:00
|
|
|
}
|