diff options
| author | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-07-27 12:32:00 +0200 |
|---|---|---|
| committer | vaxerski <43317083+vaxerski@users.noreply.github.com> | 2022-07-27 12:32:00 +0200 |
| commit | 31a079b347ddede3f672b0b059967f5e6bc74a36 (patch) | |
| tree | c957d8af9866189dbaaa71f4481e13e860ff640c /src/helpers/Monitor.cpp | |
| parent | 50b991674b6d6607477232a774d5f730789d18a8 (diff) | |
added DPMS
Diffstat (limited to 'src/helpers/Monitor.cpp')
| -rw-r--r-- | src/helpers/Monitor.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp new file mode 100644 index 00000000..8dc239fc --- /dev/null +++ b/src/helpers/Monitor.cpp @@ -0,0 +1,162 @@ +#include "Monitor.hpp" + +#include "../Compositor.hpp" + +void CMonitor::onConnect(bool noRule) { + // get monitor rule that matches + SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(output->name); + + hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this); + hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this); + + // if it's disabled, disable and ignore + if (monitorRule.disabled) { + wlr_output_enable(output, 0); + wlr_output_commit(output); + + hyprListener_monitorFrame.removeCallback(); + return; + } + + if (std::find_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](auto& other) { return other.get() == this; }) == g_pCompositor->m_vMonitors.end()){ + g_pCompositor->m_vMonitors.push_back(*m_pThisWrap); + } + + m_bEnabled = true; + + ID = g_pCompositor->getNextAvailableMonitorID(); + szName = output->name; + + wlr_output_set_scale(output, monitorRule.scale); + wlr_xcursor_manager_load(g_pCompositor->m_sWLRXCursorMgr, monitorRule.scale); + wlr_output_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL); // TODO: support other transforms + + wlr_output_enable_adaptive_sync(output, 1); + + // create it in the arr + vecPosition = monitorRule.offset; + vecSize = monitorRule.resolution; + refreshRate = monitorRule.refreshRate; + + wlr_output_enable(output, 1); + + // TODO: this doesn't seem to set the X and Y correctly, + // wlr_output_layout_output_coords returns invalid values, I think... + wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, output, monitorRule.offset.x, monitorRule.offset.y); + + // set mode, also applies + if (!noRule) + g_pHyprRenderer->applyMonitorRule(this, &monitorRule, true); + + Debug::log(LOG, "Added new monitor with name %s at %i,%i with size %ix%i, pointer %x", output->name, (int)monitorRule.offset.x, (int)monitorRule.offset.y, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, output); + + damage = wlr_output_damage_create(output); + + // add a WLR workspace group + if (!pWLRWorkspaceGroupHandle) { + pWLRWorkspaceGroupHandle = wlr_ext_workspace_group_handle_v1_create(g_pCompositor->m_sWLREXTWorkspaceMgr); + } + + wlr_ext_workspace_group_handle_v1_output_enter(pWLRWorkspaceGroupHandle, output); + + // Workspace + std::string newDefaultWorkspaceName = ""; + auto WORKSPACEID = monitorRule.defaultWorkspace == "" ? g_pCompositor->m_vWorkspaces.size() + 1 : getWorkspaceIDFromString(monitorRule.defaultWorkspace, newDefaultWorkspaceName); + + if (WORKSPACEID == INT_MAX || WORKSPACEID == (long unsigned int)SPECIAL_WORKSPACE_ID) { + WORKSPACEID = g_pCompositor->m_vWorkspaces.size() + 1; + newDefaultWorkspaceName = std::to_string(WORKSPACEID); + + Debug::log(LOG, "Invalid workspace= directive name in monitor parsing, workspace name \"%s\" is invalid.", monitorRule.defaultWorkspace.c_str()); + } + + auto PNEWWORKSPACE = g_pCompositor->getWorkspaceByID(WORKSPACEID); + + Debug::log(LOG, "New monitor: WORKSPACEID %d, exists: %d", WORKSPACEID, (int)(PNEWWORKSPACE != nullptr)); + + if (PNEWWORKSPACE) { + // workspace exists, move it to the newly connected monitor + g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, this); + activeWorkspace = PNEWWORKSPACE->m_iID; + g_pLayoutManager->getCurrentLayout()->recalculateMonitor(ID); + PNEWWORKSPACE->startAnim(true, true, true); + } else { + PNEWWORKSPACE = g_pCompositor->m_vWorkspaces.emplace_back(std::make_unique<CWorkspace>(ID, newDefaultWorkspaceName)).get(); + + // We are required to set the name here immediately + wlr_ext_workspace_handle_v1_set_name(PNEWWORKSPACE->m_pWlrHandle, newDefaultWorkspaceName.c_str()); + + PNEWWORKSPACE->m_iID = WORKSPACEID; + } + + activeWorkspace = PNEWWORKSPACE->m_iID; + scale = monitorRule.scale; + + forceFullFrames = 3; // force 3 full frames to make sure there is no blinking due to double-buffering. + + g_pCompositor->deactivateAllWLRWorkspaces(PNEWWORKSPACE->m_pWlrHandle); + PNEWWORKSPACE->setActive(true); + // + + if (!g_pCompositor->m_pLastMonitor) // set the last monitor if it isnt set yet + g_pCompositor->m_pLastMonitor = this; + + g_pEventManager->postEvent(SHyprIPCEvent{"monitoradded", szName}); +} + +void CMonitor::onDisconnect() { + // Cleanup everything. Move windows back, snap cursor, shit. + CMonitor* BACKUPMON = nullptr; + for (auto& m : g_pCompositor->m_vMonitors) { + if (m.get() != this) { + BACKUPMON = m.get(); + break; + } + } + + if (!BACKUPMON) { + Debug::log(CRIT, "No monitors! Unplugged last! Exiting."); + g_pCompositor->cleanup(); + return; + } + + m_bEnabled = false; + + hyprListener_monitorFrame.removeCallback(); + + const auto BACKUPWORKSPACE = BACKUPMON->activeWorkspace > 0 ? std::to_string(BACKUPMON->activeWorkspace) : "name:" + g_pCompositor->getWorkspaceByID(BACKUPMON->activeWorkspace)->m_szName; + + // snap cursor + wlr_cursor_warp(g_pCompositor->m_sWLRCursor, g_pCompositor->m_sSeat.mouse->mouse, BACKUPMON->vecPosition.x + BACKUPMON->vecTransformedSize.x / 2.f, BACKUPMON->vecPosition.y + BACKUPMON->vecTransformedSize.y / 2.f); + + // move workspaces + std::deque<CWorkspace*> wspToMove; + for (auto& w : g_pCompositor->m_vWorkspaces) { + if (w->m_iMonitorID == ID) { + wspToMove.push_back(w.get()); + } + } + + for (auto& w : wspToMove) { + g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON); + w->startAnim(true, true, true); + } + + activeWorkspace = -1; + + wlr_output_damage_destroy(damage); + + wlr_output_layout_remove(g_pCompositor->m_sWLROutputLayout, output); + + wlr_output_enable(output, false); + + wlr_output_commit(output); + + g_pCompositor->m_vWorkspaces.erase(std::remove_if(g_pCompositor->m_vWorkspaces.begin(), g_pCompositor->m_vWorkspaces.end(), [&](std::unique_ptr<CWorkspace>& el) { return el->m_iMonitorID == ID; })); + + Debug::log(LOG, "Removed monitor %s!", szName.c_str()); + + g_pEventManager->postEvent(SHyprIPCEvent{"monitorremoved", szName}); + + g_pCompositor->m_vMonitors.erase(std::remove_if(g_pCompositor->m_vMonitors.begin(), g_pCompositor->m_vMonitors.end(), [&](std::shared_ptr<CMonitor>& el) { return el.get() == this; })); +} |
