mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 13:09:49 +01:00
start handling monitors
This commit is contained in:
parent
cf51ab71a2
commit
d6c2553af2
9 changed files with 175 additions and 7 deletions
|
@ -3,6 +3,8 @@
|
|||
#
|
||||
# Refer to the wiki for more information.
|
||||
|
||||
monitor=,1280x720,0x0,0.5,1
|
||||
|
||||
general {
|
||||
max_fps=240
|
||||
gaps_in=5
|
||||
|
|
|
@ -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,7 +38,9 @@ public:
|
|||
|
||||
const char* m_szWLDisplaySocket;
|
||||
|
||||
void startCompositor();
|
||||
std::deque<SMonitor> m_vMonitors;
|
||||
|
||||
void startCompositor();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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};
|
||||
}
|
|
@ -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;
|
|
@ -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) {
|
||||
|
||||
}
|
||||
|
|
|
@ -22,4 +22,7 @@ namespace Events {
|
|||
|
||||
LISTENER(outputMgrApply);
|
||||
LISTENER(outputMgrTest);
|
||||
|
||||
LISTENER(monitorFrame);
|
||||
LISTENER(monitorDestroy);
|
||||
};
|
17
src/helpers/Monitor.hpp
Normal file
17
src/helpers/Monitor.hpp
Normal 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);
|
||||
};
|
|
@ -14,4 +14,9 @@ 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue