start handling monitors

This commit is contained in:
vaxerski 2022-03-17 16:56:33 +01:00
parent cf51ab71a2
commit d6c2553af2
9 changed files with 175 additions and 7 deletions

View file

@ -3,6 +3,8 @@
#
# Refer to the wiki for more information.
monitor=,1280x720,0x0,0.5,1
general {
max_fps=240
gaps_in=5

View file

@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include <deque>
#include "defines.hpp"
#include "debug/Log.hpp"
@ -8,6 +9,7 @@
#include "config/ConfigManager.hpp"
#include "ManagerThread.hpp"
#include "input/InputManager.hpp"
#include "helpers/Monitor.hpp"
class CCompositor {
public:
@ -36,6 +38,8 @@ public:
const char* m_szWLDisplaySocket;
std::deque<SMonitor> m_vMonitors;
void startCompositor();
};

View file

@ -66,6 +66,52 @@ void CConfigManager::handleRawExec(const std::string& command, const std::string
}
}
void CConfigManager::handleMonitor(const std::string& command, const std::string& args) {
// get the monitor config
SMonitorRule newrule;
std::string curitem = "";
std::string argZ = args;
auto nextItem = [&]() {
auto idx = argZ.find_first_of(',');
if (idx != std::string::npos) {
curitem = argZ.substr(0, idx);
argZ = argZ.substr(idx + 1);
} else {
argZ = "";
curitem = argZ;
}
};
nextItem();
newrule.name = curitem;
nextItem();
newrule.resolution.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
newrule.resolution.y = stoi(curitem.substr(curitem.find_first_of('x') + 1));
nextItem();
newrule.offset.x = stoi(curitem.substr(0, curitem.find_first_of('x')));
newrule.offset.y = stoi(curitem.substr(curitem.find_first_of('x') + 1));
nextItem();
newrule.mfact = stof(curitem);
nextItem();
newrule.scale = stof(curitem);
m_dMonitorRules.push_back(newrule);
}
void CConfigManager::parseLine(std::string& line) {
// first check if its not a comment
const auto COMMENTSTART = line.find_first_of('#');
@ -111,6 +157,9 @@ void CConfigManager::parseLine(std::string& line) {
handleRawExec(COMMAND, VALUE);
return;
}
} else if (COMMAND == "monitor") {
handleMonitor(COMMAND, VALUE);
return;
}
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
@ -121,6 +170,8 @@ void CConfigManager::loadConfigLoadVars() {
parseError = ""; // reset the error
currentCategory = ""; // reset the category
m_dMonitorRules.clear();
const char* const ENVHOME = getenv("HOME");
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
@ -199,3 +250,29 @@ float CConfigManager::getFloat(std::string v) {
std::string CConfigManager::getString(std::string v) {
return getConfigValueSafe(v).strValue;
}
SMonitorRule CConfigManager::getMonitorRuleFor(std::string name) {
SMonitorRule* found = nullptr;
for (auto& r : m_dMonitorRules) {
if (r.name == name) {
found = &r;
break;
}
}
if (found)
return *found;
for (auto& r : m_dMonitorRules) {
if (r.name == "") {
found = &r;
break;
}
}
if (found)
return *found;
return SMonitorRule{.name = "", .resolution = Vector2D(1280, 720), .offset = Vector2D(0, 0), .mfact = 0.5f, .scale = 1};
}

View file

@ -5,6 +5,7 @@
#include <unordered_map>
#include "../defines.hpp"
#include <vector>
#include <deque>
struct SConfigValue {
int64_t intValue = -1;
@ -12,6 +13,14 @@ struct SConfigValue {
std::string strValue = "";
};
struct SMonitorRule {
std::string name = "";
Vector2D resolution = Vector2D(1280,720);
Vector2D offset = Vector2D(0,0);
float mfact = 0.5;
float scale = 1;
};
class CConfigManager {
public:
CConfigManager();
@ -22,6 +31,8 @@ public:
float getFloat(std::string);
std::string getString(std::string);
SMonitorRule getMonitorRuleFor(std::string);
private:
std::unordered_map<std::string, SConfigValue> configValues;
time_t lastModifyTime = 0; // for reloading the config if changed
@ -32,12 +43,15 @@ private:
bool isFirstLaunch = true; // For exec-once
std::deque<SMonitorRule> m_dMonitorRules;
// internal methods
void loadConfigLoadVars();
SConfigValue getConfigValueSafe(std::string);
void parseLine(std::string&);
void configSetValueSafe(const std::string&, const std::string&);
void handleRawExec(const std::string&, const std::string&);
void handleMonitor(const std::string&, const std::string&);
};
inline std::unique_ptr<CConfigManager> g_pConfigManager;

View file

@ -1,11 +1,61 @@
#include "Events.hpp"
#include "../input/InputManager.hpp"
#include "../Compositor.hpp"
void Events::listener_activate(wl_listener* listener, void* data) {
}
void Events::listener_change(wl_listener* listener, void* data) {
// layout got changed, let's update monitors.
const auto CONFIG = wlr_output_configuration_v1_create();
const auto GEOMETRY = wlr_output_layout_get_box(g_pCompositor->m_sWLROutputLayout, NULL);
}
void Events::listener_newOutput(wl_listener* listener, void* data) {
// new monitor added, let's accomodate for that.
const auto OUTPUT = (wlr_output*)data;
SMonitor newMonitor;
wlr_output_init_render(OUTPUT, g_pCompositor->m_sWLRAllocator, g_pCompositor->m_sWLRRenderer);
// get monitor rule that matches
SMonitorRule monitorRule = g_pConfigManager->getMonitorRuleFor(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_set_mode(OUTPUT, wlr_output_preferred_mode(OUTPUT));
wlr_output_enable_adaptive_sync(OUTPUT, 1);
wl_signal_add(&OUTPUT->events.frame, &Events::listen_monitorFrame);
wl_signal_add(&OUTPUT->events.destroy, &Events::listen_monitorDestroy);
wlr_output_enable(OUTPUT, 1);
if (!wlr_output_commit(OUTPUT)) {
Debug::log(ERR, "Couldn't commit output named %s", OUTPUT->name);
return;
}
wlr_output_layout_add(g_pCompositor->m_sWLROutputLayout, OUTPUT, monitorRule.offset.x, monitorRule.offset.y);
// add new monitor to our internal arr
newMonitor.ID = g_pCompositor->m_vMonitors.size();
newMonitor.szName = OUTPUT->name;
newMonitor.vecPosition = monitorRule.offset;
newMonitor.vecSize = monitorRule.resolution;
g_pCompositor->m_vMonitors.push_back(newMonitor);
}
void Events::listener_monitorFrame(wl_listener* listener, void* data) {
}
void Events::listener_monitorDestroy(wl_listener* listener, void* data) {
}
@ -41,10 +91,6 @@ void Events::listener_newLayerSurface(wl_listener* listener, void* data) {
}
void Events::listener_newOutput(wl_listener* listener, void* data) {
}
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
}

View file

@ -22,4 +22,7 @@ namespace Events {
LISTENER(outputMgrApply);
LISTENER(outputMgrTest);
LISTENER(monitorFrame);
LISTENER(monitorDestroy);
};

17
src/helpers/Monitor.hpp Normal file
View file

@ -0,0 +1,17 @@
#pragma once
#include "../defines.hpp"
struct SMonitor {
Vector2D vecPosition = Vector2D(0,0);
Vector2D vecSize = Vector2D(0,0);
bool primary = false;
int ID = -1;
std::string szName = "";
Vector2D vecReservedTopLeft = Vector2D(0,0);
Vector2D vecReservedBottomRight = Vector2D(0,0);
};

View file

@ -15,3 +15,8 @@ void CInputManager::onMouseMoved(wlr_event_pointer_motion* e) {
wlr_cursor_move(g_pCompositor->m_sWLRCursor, e->device, delta.floor().x, delta.floor().y);
}
}
void CInputManager::onMouseWarp(wlr_event_pointer_motion_absolute* e) {
wlr_cursor_warp_absolute(g_pCompositor->m_sWLRCursor, e->device, e->x, e->y);
}

View file

@ -6,7 +6,7 @@ class CInputManager {
public:
void onMouseMoved(wlr_event_pointer_motion*);
void onMouseButton(int);
void onMouseWarp(wlr_event_pointer_motion_absolute*);
private:
Vector2D m_vMouseCoords = Vector2D(0,0);