mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-30 01:45:58 +01:00
xdgoutput: separate logic for zero scaling positions
if a scaled monitor was directly to the left of another monitor, we'd change the size to have zero scaling without pushing other monitors out of the way, creating overlaps in xwayland.
This commit is contained in:
parent
7c4daee29a
commit
347a1eb662
2 changed files with 45 additions and 3 deletions
|
@ -97,7 +97,7 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* r
|
||||||
if (XDGVER >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION && PMONITOR->output->description)
|
if (XDGVER >= ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION && PMONITOR->output->description)
|
||||||
zxdg_output_v1_send_description(pXDGOutput->resource->resource(), PMONITOR->output->description);
|
zxdg_output_v1_send_description(pXDGOutput->resource->resource(), PMONITOR->output->description);
|
||||||
|
|
||||||
updateOutputDetails(pXDGOutput);
|
updateAllOutputs();
|
||||||
|
|
||||||
const auto OUTPUTVER = wl_resource_get_version(outputResource);
|
const auto OUTPUTVER = wl_resource_get_version(outputResource);
|
||||||
if (OUTPUTVER >= WL_OUTPUT_DONE_SINCE_VERSION && XDGVER >= OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
if (OUTPUTVER >= WL_OUTPUT_DONE_SINCE_VERSION && XDGVER >= OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
||||||
|
@ -107,10 +107,11 @@ void CXDGOutputProtocol::onManagerGetXDGOutput(wl_client* client, wl_resource* r
|
||||||
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
||||||
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
||||||
|
|
||||||
zxdg_output_v1_send_logical_position(pOutput->resource->resource(), pOutput->monitor->vecPosition.x, pOutput->monitor->vecPosition.y);
|
const auto POS = pOutput->overridePosition.value_or(pOutput->monitor->vecPosition);
|
||||||
|
zxdg_output_v1_send_logical_position(pOutput->resource->resource(), POS.x, POS.y);
|
||||||
|
|
||||||
if (*PXWLFORCESCALEZERO && pOutput->isXWayland)
|
if (*PXWLFORCESCALEZERO && pOutput->isXWayland)
|
||||||
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecPixelSize.x, pOutput->monitor->vecPixelSize.y);
|
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecTransformedSize.x, pOutput->monitor->vecTransformedSize.y);
|
||||||
else
|
else
|
||||||
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecSize.x, pOutput->monitor->vecSize.y);
|
zxdg_output_v1_send_logical_size(pOutput->resource->resource(), pOutput->monitor->vecSize.x, pOutput->monitor->vecSize.y);
|
||||||
|
|
||||||
|
@ -119,9 +120,47 @@ void CXDGOutputProtocol::updateOutputDetails(SXDGOutput* pOutput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXDGOutputProtocol::updateAllOutputs() {
|
void CXDGOutputProtocol::updateAllOutputs() {
|
||||||
|
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
||||||
|
std::vector<SXDGOutput*> xwlOutputs;
|
||||||
|
|
||||||
for (auto& o : m_vXDGOutputs) {
|
for (auto& o : m_vXDGOutputs) {
|
||||||
|
if (o->isXWayland && *PXWLFORCESCALEZERO) {
|
||||||
|
xwlOutputs.push_back(o.get());
|
||||||
|
o->overridePosition.reset();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
updateOutputDetails(o.get());
|
updateOutputDetails(o.get());
|
||||||
|
|
||||||
wlr_output_schedule_done(o->monitor->output);
|
wlr_output_schedule_done(o->monitor->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all of this will be noop if force_zero_scaling is off
|
||||||
|
std::sort(xwlOutputs.begin(), xwlOutputs.end(), [&](const auto& a, const auto& b) { return a->monitor->vecPosition < b->monitor->vecPosition; });
|
||||||
|
|
||||||
|
for (auto& o : xwlOutputs) {
|
||||||
|
Vector2D suggestedPos = o->monitor->vecPosition;
|
||||||
|
|
||||||
|
// check for overlaps
|
||||||
|
for (auto& o1 : xwlOutputs) {
|
||||||
|
if (!o1->overridePosition.has_value())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto OPOS = o1->overridePosition.value();
|
||||||
|
|
||||||
|
if (OPOS.x + o1->monitor->vecTransformedSize.x > suggestedPos.x && /* Y overlap */
|
||||||
|
!(suggestedPos.y + o->monitor->vecTransformedSize.y <= OPOS.y || OPOS.y + o1->monitor->vecTransformedSize.y <= suggestedPos.y))
|
||||||
|
suggestedPos.x = OPOS.x + o1->monitor->vecTransformedSize.x;
|
||||||
|
|
||||||
|
if (OPOS.y + o1->monitor->vecTransformedSize.y > suggestedPos.y && /* X overlap */
|
||||||
|
!(suggestedPos.x + o->monitor->vecTransformedSize.x <= OPOS.x || OPOS.x + o1->monitor->vecTransformedSize.x <= suggestedPos.x))
|
||||||
|
suggestedPos.y = OPOS.y + o1->monitor->vecTransformedSize.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
o->overridePosition = suggestedPos;
|
||||||
|
|
||||||
|
updateOutputDetails(o);
|
||||||
|
|
||||||
|
wlr_output_schedule_done(o->monitor->output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WaylandProtocol.hpp"
|
#include "WaylandProtocol.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
class CMonitor;
|
class CMonitor;
|
||||||
|
|
||||||
|
@ -8,6 +9,8 @@ struct SXDGOutput {
|
||||||
CMonitor* monitor = nullptr;
|
CMonitor* monitor = nullptr;
|
||||||
std::unique_ptr<CWaylandResource> resource;
|
std::unique_ptr<CWaylandResource> resource;
|
||||||
|
|
||||||
|
std::optional<Vector2D> overridePosition;
|
||||||
|
|
||||||
wl_client* client = nullptr;
|
wl_client* client = nullptr;
|
||||||
bool isXWayland = false;
|
bool isXWayland = false;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue