mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 16:45:59 +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.
|
# Refer to the wiki for more information.
|
||||||
|
|
||||||
|
monitor=,1280x720,0x0,0.5,1
|
||||||
|
|
||||||
general {
|
general {
|
||||||
max_fps=240
|
max_fps=240
|
||||||
gaps_in=5
|
gaps_in=5
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
#include "debug/Log.hpp"
|
#include "debug/Log.hpp"
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
#include "config/ConfigManager.hpp"
|
#include "config/ConfigManager.hpp"
|
||||||
#include "ManagerThread.hpp"
|
#include "ManagerThread.hpp"
|
||||||
#include "input/InputManager.hpp"
|
#include "input/InputManager.hpp"
|
||||||
|
#include "helpers/Monitor.hpp"
|
||||||
|
|
||||||
class CCompositor {
|
class CCompositor {
|
||||||
public:
|
public:
|
||||||
|
@ -36,6 +38,8 @@ public:
|
||||||
|
|
||||||
const char* m_szWLDisplaySocket;
|
const char* m_szWLDisplaySocket;
|
||||||
|
|
||||||
|
std::deque<SMonitor> m_vMonitors;
|
||||||
|
|
||||||
void startCompositor();
|
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) {
|
void CConfigManager::parseLine(std::string& line) {
|
||||||
// first check if its not a comment
|
// first check if its not a comment
|
||||||
const auto COMMENTSTART = line.find_first_of('#');
|
const auto COMMENTSTART = line.find_first_of('#');
|
||||||
|
@ -111,6 +157,9 @@ void CConfigManager::parseLine(std::string& line) {
|
||||||
handleRawExec(COMMAND, VALUE);
|
handleRawExec(COMMAND, VALUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (COMMAND == "monitor") {
|
||||||
|
handleMonitor(COMMAND, VALUE);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
configSetValueSafe(currentCategory + (currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||||
|
@ -121,6 +170,8 @@ void CConfigManager::loadConfigLoadVars() {
|
||||||
parseError = ""; // reset the error
|
parseError = ""; // reset the error
|
||||||
currentCategory = ""; // reset the category
|
currentCategory = ""; // reset the category
|
||||||
|
|
||||||
|
m_dMonitorRules.clear();
|
||||||
|
|
||||||
const char* const ENVHOME = getenv("HOME");
|
const char* const ENVHOME = getenv("HOME");
|
||||||
const std::string CONFIGPATH = ENVHOME + (ISDEBUG ? (std::string) "/.config/hypr/hyprlandd.conf" : (std::string) "/.config/hypr/hyprland.conf");
|
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) {
|
std::string CConfigManager::getString(std::string v) {
|
||||||
return getConfigValueSafe(v).strValue;
|
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 <unordered_map>
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
struct SConfigValue {
|
struct SConfigValue {
|
||||||
int64_t intValue = -1;
|
int64_t intValue = -1;
|
||||||
|
@ -12,6 +13,14 @@ struct SConfigValue {
|
||||||
std::string strValue = "";
|
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 {
|
class CConfigManager {
|
||||||
public:
|
public:
|
||||||
CConfigManager();
|
CConfigManager();
|
||||||
|
@ -22,6 +31,8 @@ public:
|
||||||
float getFloat(std::string);
|
float getFloat(std::string);
|
||||||
std::string getString(std::string);
|
std::string getString(std::string);
|
||||||
|
|
||||||
|
SMonitorRule getMonitorRuleFor(std::string);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, SConfigValue> configValues;
|
std::unordered_map<std::string, SConfigValue> configValues;
|
||||||
time_t lastModifyTime = 0; // for reloading the config if changed
|
time_t lastModifyTime = 0; // for reloading the config if changed
|
||||||
|
@ -32,12 +43,15 @@ private:
|
||||||
|
|
||||||
bool isFirstLaunch = true; // For exec-once
|
bool isFirstLaunch = true; // For exec-once
|
||||||
|
|
||||||
|
std::deque<SMonitorRule> m_dMonitorRules;
|
||||||
|
|
||||||
// internal methods
|
// internal methods
|
||||||
void loadConfigLoadVars();
|
void loadConfigLoadVars();
|
||||||
SConfigValue getConfigValueSafe(std::string);
|
SConfigValue getConfigValueSafe(std::string);
|
||||||
void parseLine(std::string&);
|
void parseLine(std::string&);
|
||||||
void configSetValueSafe(const std::string&, const std::string&);
|
void configSetValueSafe(const std::string&, const std::string&);
|
||||||
void handleRawExec(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;
|
inline std::unique_ptr<CConfigManager> g_pConfigManager;
|
|
@ -1,11 +1,61 @@
|
||||||
#include "Events.hpp"
|
#include "Events.hpp"
|
||||||
#include "../input/InputManager.hpp"
|
#include "../input/InputManager.hpp"
|
||||||
|
#include "../Compositor.hpp"
|
||||||
|
|
||||||
void Events::listener_activate(wl_listener* listener, void* data) {
|
void Events::listener_activate(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_change(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) {
|
void Events::listener_newXDGSurface(wl_listener* listener, void* data) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,7 @@ namespace Events {
|
||||||
|
|
||||||
LISTENER(outputMgrApply);
|
LISTENER(outputMgrApply);
|
||||||
LISTENER(outputMgrTest);
|
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);
|
||||||
|
};
|
|
@ -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);
|
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:
|
public:
|
||||||
|
|
||||||
void onMouseMoved(wlr_event_pointer_motion*);
|
void onMouseMoved(wlr_event_pointer_motion*);
|
||||||
void onMouseButton(int);
|
void onMouseWarp(wlr_event_pointer_motion_absolute*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector2D m_vMouseCoords = Vector2D(0,0);
|
Vector2D m_vMouseCoords = Vector2D(0,0);
|
||||||
|
|
Loading…
Reference in a new issue