From 5d529d46e772b754397c3381cc73015acefbea7f Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Wed, 13 Apr 2022 17:11:37 +0200 Subject: [PATCH] use output's modes instead of a custom mode --- src/defines.hpp | 2 ++ src/events/Monitors.cpp | 54 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/defines.hpp b/src/defines.hpp index 4bd5f239..8b810fd5 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -21,6 +21,8 @@ #define VECINRECT(vec, x1, y1, x2, y2) (vec.x >= (x1) && vec.x <= (x2) && vec.y >= (y1) && vec.y <= (y2)) +#define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < delta) + #define interface class #define STICKS(a, b) abs((a) - (b)) < 2 diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index ef9518fc..85b76abd 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -74,16 +74,60 @@ void Events::listener_newOutput(wl_listener* listener, void* data) { PNEWMONITOR->hyprListener_monitorDestroy.initCallback(&OUTPUT->events.destroy, &Events::listener_monitorDestroy, PNEWMONITOR); wlr_output_enable(OUTPUT, 1); - if (!wlr_output_commit(OUTPUT)) { - Debug::log(ERR, "Couldn't commit output named %s", OUTPUT->name); - return; - } // 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); - wlr_output_set_custom_mode(OUTPUT, OUTPUT->width, OUTPUT->height, (int)(round(monitorRule.refreshRate * 1000))); + // loop over modes and choose an appropriate one. + if (!wl_list_empty(&OUTPUT->modes)) { + wlr_output_mode* mode; + bool found = false; + + wl_list_for_each(mode, &OUTPUT->modes, link) { + // if delta of refresh rate, w and h chosen and mode is < 1 we accept it + if (DELTALESSTHAN(mode->width, monitorRule.resolution.x, 1) && DELTALESSTHAN(mode->height, monitorRule.resolution.y, 1) && DELTALESSTHAN(mode->refresh / 1000.f, monitorRule.refreshRate, 1)) { + wlr_output_set_mode(OUTPUT, mode); + + if (!wlr_output_test(OUTPUT)) { + Debug::log(LOG, "Monitor %s: REJECTED available mode: %ix%i@%2f!", + OUTPUT->name, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, (float)monitorRule.refreshRate, + mode->width, mode->height, mode->refresh / 1000.f); + continue; + } + + Debug::log(LOG, "Monitor %s: requested %ix%i@%2f, found available mode: %ix%i@%2f, applying.", + OUTPUT->name, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, (float)monitorRule.refreshRate, + mode->width, mode->height, mode->refresh / 1000.f); + + found = true; + + break; + } + } + + if (!found) { + const auto PREFERREDMODE = wlr_output_preferred_mode(OUTPUT); + + if (!PREFERREDMODE) { + Debug::log(ERR, "Monitor %s has NO PREFERRED MODE, and an INVALID one was requested: %ix%i@%2f", + (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, (float)monitorRule.refreshRate); + return; + } + + // Preferred is valid + wlr_output_set_mode(OUTPUT, PREFERREDMODE); + + Debug::log(ERR, "Monitor %s got an invalid requested mode: %ix%i@%2f, using the preferred one instead: %ix%i@%2f", + OUTPUT->name, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, (float)monitorRule.refreshRate, + PREFERREDMODE->width, PREFERREDMODE->height, PREFERREDMODE->refresh / 1000.f); + } + } + + if (!wlr_output_commit(OUTPUT)) { + Debug::log(ERR, "Couldn't commit output named %s", OUTPUT->name); + return; + } Debug::log(LOG, "Added new monitor with name %s at %i,%i with size %ix%i@%i, pointer %x", OUTPUT->name, (int)monitorRule.offset.x, (int)monitorRule.offset.y, (int)monitorRule.resolution.x, (int)monitorRule.resolution.y, (int)monitorRule.refreshRate, OUTPUT);