mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 11:05:58 +01:00
xwayland: send zero scaling to xwayland if enabled
This commit is contained in:
parent
69fae18e63
commit
01f85a09a9
15 changed files with 109 additions and 11 deletions
|
@ -197,5 +197,6 @@ protocol("subprojects/hyprland-protocols/protocols/hyprland-global-shortcuts-v1.
|
||||||
protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.xml" "hyprland-toplevel-export-v1" true)
|
protocol("subprojects/hyprland-protocols/protocols/hyprland-toplevel-export-v1.xml" "hyprland-toplevel-export-v1" true)
|
||||||
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
|
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
|
||||||
protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false)
|
protocol("unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml" "linux-dmabuf-unstable-v1" false)
|
||||||
|
protocol("unstable/xdg-output/xdg-output-unstable-v1.xml" "xdg-output-unstable-v1" false)
|
||||||
protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
||||||
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
protocol("unstable/text-input/text-input-unstable-v1.xml" "text-input-unstable-v1" false)
|
||||||
|
|
|
@ -22,6 +22,7 @@ protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
[wl_protocol_dir, 'unstable/text-input/text-input-unstable-v1.xml'],
|
||||||
|
[wl_protocol_dir, 'unstable/xdg-output/xdg-output-unstable-v1.xml'],
|
||||||
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
[wl_protocol_dir, 'staging/fractional-scale/fractional-scale-v1.xml'],
|
||||||
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
['wlr-foreign-toplevel-management-unstable-v1.xml'],
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
|
|
|
@ -194,7 +194,7 @@ void CCompositor::initServer() {
|
||||||
m_sWLRXDGDecoMgr = wlr_xdg_decoration_manager_v1_create(m_sWLDisplay);
|
m_sWLRXDGDecoMgr = wlr_xdg_decoration_manager_v1_create(m_sWLDisplay);
|
||||||
wlr_server_decoration_manager_set_default_mode(m_sWLRServerDecoMgr, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
wlr_server_decoration_manager_set_default_mode(m_sWLRServerDecoMgr, WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||||
|
|
||||||
wlr_xdg_output_manager_v1_create(m_sWLDisplay, m_sWLROutputLayout);
|
m_sWLRXDGOutputMgr = wlr_xdg_output_manager_v1_create(m_sWLDisplay, m_sWLROutputLayout);
|
||||||
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
m_sWLROutputMgr = wlr_output_manager_v1_create(m_sWLDisplay);
|
||||||
|
|
||||||
m_sWLRInhibitMgr = wlr_input_inhibit_manager_create(m_sWLDisplay);
|
m_sWLRInhibitMgr = wlr_input_inhibit_manager_create(m_sWLDisplay);
|
||||||
|
|
|
@ -60,6 +60,7 @@ class CCompositor {
|
||||||
wlr_xcursor_manager* m_sWLRXCursorMgr;
|
wlr_xcursor_manager* m_sWLRXCursorMgr;
|
||||||
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
|
wlr_virtual_keyboard_manager_v1* m_sWLRVKeyboardMgr;
|
||||||
wlr_output_manager_v1* m_sWLROutputMgr;
|
wlr_output_manager_v1* m_sWLROutputMgr;
|
||||||
|
wlr_xdg_output_manager_v1* m_sWLRXDGOutputMgr;
|
||||||
wlr_presentation* m_sWLRPresentation;
|
wlr_presentation* m_sWLRPresentation;
|
||||||
wlr_scene* m_sWLRScene;
|
wlr_scene* m_sWLRScene;
|
||||||
wlr_input_inhibit_manager* m_sWLRInhibitMgr;
|
wlr_input_inhibit_manager* m_sWLRInhibitMgr;
|
||||||
|
|
|
@ -1567,6 +1567,9 @@ void CConfigManager::loadConfigLoadVars() {
|
||||||
// update layout
|
// update layout
|
||||||
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
g_pLayoutManager->switchToLayout(configValues["general:layout"].strValue);
|
||||||
|
|
||||||
|
// update xwl scale
|
||||||
|
g_pXWaylandManager->updateXWaylandScale();
|
||||||
|
|
||||||
// manual crash
|
// manual crash
|
||||||
if (configValues["debug:manual_crash"].intValue && !m_bManualCrashInitiated) {
|
if (configValues["debug:manual_crash"].intValue && !m_bManualCrashInitiated) {
|
||||||
m_bManualCrashInitiated = true;
|
m_bManualCrashInitiated = true;
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace Events {
|
||||||
DYNLISTENFUNC(monitorDamage);
|
DYNLISTENFUNC(monitorDamage);
|
||||||
DYNLISTENFUNC(monitorNeedsFrame);
|
DYNLISTENFUNC(monitorNeedsFrame);
|
||||||
DYNLISTENFUNC(monitorCommit);
|
DYNLISTENFUNC(monitorCommit);
|
||||||
|
DYNLISTENFUNC(monitorBind);
|
||||||
|
|
||||||
// XWayland
|
// XWayland
|
||||||
LISTENER(readyXWayland);
|
LISTENER(readyXWayland);
|
||||||
|
|
|
@ -74,6 +74,8 @@ void Events::listener_readyXWayland(wl_listener* listener, void* data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_disconnect(XCBCONNECTION);
|
xcb_disconnect(XCBCONNECTION);
|
||||||
|
|
||||||
|
g_pXWaylandManager->updateXWaylandScale();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,4 +218,11 @@ void Events::listener_monitorCommit(void* owner, void* data) {
|
||||||
const auto E = (wlr_output_event_commit*)data;
|
const auto E = (wlr_output_event_commit*)data;
|
||||||
|
|
||||||
g_pProtocolManager->m_pScreencopyProtocolManager->onOutputCommit(PMONITOR, E);
|
g_pProtocolManager->m_pScreencopyProtocolManager->onOutputCommit(PMONITOR, E);
|
||||||
|
|
||||||
|
if (E->committed & (WLR_OUTPUT_STATE_SCALE | WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_MODE))
|
||||||
|
g_pXWaylandManager->updateXWaylandScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::listener_monitorBind(void* owner, void* data) {
|
||||||
|
g_pXWaylandManager->updateXWaylandScale();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,12 +23,14 @@ void CMonitor::onConnect(bool noRule) {
|
||||||
hyprListener_monitorDamage.removeCallback();
|
hyprListener_monitorDamage.removeCallback();
|
||||||
hyprListener_monitorNeedsFrame.removeCallback();
|
hyprListener_monitorNeedsFrame.removeCallback();
|
||||||
hyprListener_monitorCommit.removeCallback();
|
hyprListener_monitorCommit.removeCallback();
|
||||||
|
hyprListener_monitorBind.removeCallback();
|
||||||
hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this);
|
hyprListener_monitorFrame.initCallback(&output->events.frame, &Events::listener_monitorFrame, this);
|
||||||
hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this);
|
hyprListener_monitorDestroy.initCallback(&output->events.destroy, &Events::listener_monitorDestroy, this);
|
||||||
hyprListener_monitorStateRequest.initCallback(&output->events.request_state, &Events::listener_monitorStateRequest, this);
|
hyprListener_monitorStateRequest.initCallback(&output->events.request_state, &Events::listener_monitorStateRequest, this);
|
||||||
hyprListener_monitorDamage.initCallback(&output->events.damage, &Events::listener_monitorDamage, this);
|
hyprListener_monitorDamage.initCallback(&output->events.damage, &Events::listener_monitorDamage, this);
|
||||||
hyprListener_monitorNeedsFrame.initCallback(&output->events.needs_frame, &Events::listener_monitorNeedsFrame, this);
|
hyprListener_monitorNeedsFrame.initCallback(&output->events.needs_frame, &Events::listener_monitorNeedsFrame, this);
|
||||||
hyprListener_monitorCommit.initCallback(&output->events.commit, &Events::listener_monitorCommit, this);
|
hyprListener_monitorCommit.initCallback(&output->events.commit, &Events::listener_monitorCommit, this);
|
||||||
|
hyprListener_monitorBind.initCallback(&output->events.bind, &Events::listener_monitorBind, this);
|
||||||
|
|
||||||
if (m_bEnabled) {
|
if (m_bEnabled) {
|
||||||
wlr_output_enable(output, 1);
|
wlr_output_enable(output, 1);
|
||||||
|
|
|
@ -72,6 +72,7 @@ class CMonitor {
|
||||||
DYNLISTENER(monitorDamage);
|
DYNLISTENER(monitorDamage);
|
||||||
DYNLISTENER(monitorNeedsFrame);
|
DYNLISTENER(monitorNeedsFrame);
|
||||||
DYNLISTENER(monitorCommit);
|
DYNLISTENER(monitorCommit);
|
||||||
|
DYNLISTENER(monitorBind);
|
||||||
|
|
||||||
// hack: a group = workspaces on a monitor.
|
// hack: a group = workspaces on a monitor.
|
||||||
// I don't really care lol :P
|
// I don't really care lol :P
|
||||||
|
|
|
@ -24,15 +24,15 @@ double Vector2D::normalize() {
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D Vector2D::floor() {
|
Vector2D Vector2D::floor() const {
|
||||||
return Vector2D(std::floor(x), std::floor(y));
|
return Vector2D(std::floor(x), std::floor(y));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) {
|
Vector2D Vector2D::clamp(const Vector2D& min, const Vector2D& max) const {
|
||||||
return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y));
|
return Vector2D(std::clamp(this->x, min.x, max.x < min.x ? INFINITY : max.x), std::clamp(this->y, min.y, max.y < min.y ? INFINITY : max.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
double Vector2D::distance(const Vector2D& other) {
|
double Vector2D::distance(const Vector2D& other) const {
|
||||||
double dx = x - other.x;
|
double dx = x - other.x;
|
||||||
double dy = y - other.y;
|
double dy = y - other.y;
|
||||||
return std::sqrt(dx * dx + dy * dy);
|
return std::sqrt(dx * dx + dy * dy);
|
||||||
|
|
|
@ -43,9 +43,9 @@ class Vector2D {
|
||||||
return Vector2D(this->x / a.x, this->y / a.y);
|
return Vector2D(this->x / a.x, this->y / a.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
double distance(const Vector2D& other);
|
double distance(const Vector2D& other) const;
|
||||||
|
|
||||||
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D());
|
Vector2D clamp(const Vector2D& min, const Vector2D& max = Vector2D()) const;
|
||||||
|
|
||||||
Vector2D floor();
|
Vector2D floor() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#include "XWaylandManager.hpp"
|
#include "XWaylandManager.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
#include "../events/Events.hpp"
|
#include "../events/Events.hpp"
|
||||||
|
#include "xdg-output-unstable-v1-protocol.h"
|
||||||
|
|
||||||
|
#define OUTPUT_MANAGER_VERSION 3
|
||||||
|
#define OUTPUT_DONE_DEPRECATED_SINCE_VERSION 3
|
||||||
|
#define OUTPUT_DESCRIPTION_MUTABLE_SINCE_VERSION 3
|
||||||
|
|
||||||
CHyprXWaylandManager::CHyprXWaylandManager() {
|
CHyprXWaylandManager::CHyprXWaylandManager() {
|
||||||
#ifndef NO_XWAYLAND
|
#ifndef NO_XWAYLAND
|
||||||
|
@ -155,8 +160,10 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Vector2D POS = *PXWLFORCESCALEZERO && pWindow->m_bIsX11 ? pWindow->m_vRealPosition.vec() * pWindow->m_fX11SurfaceScaledBy : pWindow->m_vRealPosition.vec();
|
||||||
|
|
||||||
if (pWindow->m_bIsX11)
|
if (pWindow->m_bIsX11)
|
||||||
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, size.x, size.y);
|
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, POS.x, POS.y, size.x, size.y);
|
||||||
else
|
else
|
||||||
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
|
wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
@ -289,3 +296,68 @@ Vector2D CHyprXWaylandManager::getMaxSizeForWindow(CWindow* pWindow) {
|
||||||
|
|
||||||
return MAXSIZE;
|
return MAXSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprXWaylandManager::updateXWaylandScale() {
|
||||||
|
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
|
||||||
|
|
||||||
|
setXWaylandScale(*PXWLFORCESCALEZERO ? std::optional<double>{1.0} : std::optional<double>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprXWaylandManager::setXWaylandScale(std::optional<double> scale) {
|
||||||
|
Debug::log(LOG, "Overriding XWayland scale with %.2f", (float)scale.value_or(0.0));
|
||||||
|
|
||||||
|
#ifndef NO_XWAYLAND
|
||||||
|
wl_resource* res = nullptr;
|
||||||
|
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||||
|
const Vector2D LOGICALSIZE = m->vecTransformedSize / scale.value_or(m->scale);
|
||||||
|
|
||||||
|
wl_resource* outputResource = nullptr;
|
||||||
|
bool needsDone = false;
|
||||||
|
|
||||||
|
wl_list_for_each(res, &m->output->resources, link) {
|
||||||
|
const auto PCLIENT = wl_resource_get_client(res);
|
||||||
|
|
||||||
|
if (PCLIENT == m_sWLRXWayland->server->client) {
|
||||||
|
const auto VERSION = wl_resource_get_version(res);
|
||||||
|
|
||||||
|
wl_output_send_mode(res, WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED, (int32_t)LOGICALSIZE.x, (int32_t)LOGICALSIZE.y, m->output->refresh);
|
||||||
|
|
||||||
|
if (VERSION >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
||||||
|
wl_output_send_scale(res, (uint32_t)ceil(scale.value_or(m->scale)));
|
||||||
|
|
||||||
|
wl_output_send_name(res, getFormat("HL X11 %d", m->ID).c_str());
|
||||||
|
|
||||||
|
outputResource = res;
|
||||||
|
needsDone = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_xdg_output_v1* output;
|
||||||
|
wl_list_for_each(output, &g_pCompositor->m_sWLRXDGOutputMgr->outputs, link) {
|
||||||
|
if (output->layout_output->output == m->output) {
|
||||||
|
wl_list_for_each(res, &output->resources, link) {
|
||||||
|
const auto PCLIENT = wl_resource_get_client(res);
|
||||||
|
|
||||||
|
if (PCLIENT == m_sWLRXWayland->server->client) {
|
||||||
|
zxdg_output_v1_send_logical_size(res, LOGICALSIZE.x, LOGICALSIZE.y);
|
||||||
|
|
||||||
|
if (wl_resource_get_version(res) < OUTPUT_DONE_DEPRECATED_SINCE_VERSION)
|
||||||
|
zxdg_output_v1_send_done(res);
|
||||||
|
|
||||||
|
needsDone = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsDone && outputResource)
|
||||||
|
wl_output_send_done(outputResource);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../Window.hpp"
|
#include "../Window.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
class CHyprXWaylandManager {
|
class CHyprXWaylandManager {
|
||||||
public:
|
public:
|
||||||
|
@ -25,6 +26,10 @@ class CHyprXWaylandManager {
|
||||||
void moveXWaylandWindow(CWindow*, const Vector2D&);
|
void moveXWaylandWindow(CWindow*, const Vector2D&);
|
||||||
void checkBorders(CWindow*);
|
void checkBorders(CWindow*);
|
||||||
Vector2D getMaxSizeForWindow(CWindow*);
|
Vector2D getMaxSizeForWindow(CWindow*);
|
||||||
|
void updateXWaylandScale();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setXWaylandScale(std::optional<double> scale);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CHyprXWaylandManager> g_pXWaylandManager;
|
inline std::unique_ptr<CHyprXWaylandManager> g_pXWaylandManager;
|
|
@ -1880,6 +1880,8 @@ bool CHyprRenderer::applyMonitorRule(CMonitor* pMonitor, SMonitorRule* pMonitorR
|
||||||
(int)pMonitor->vecPixelSize.y, pMonitor->refreshRate, pMonitor->scale, (int)pMonitor->transform, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y,
|
(int)pMonitor->vecPixelSize.y, pMonitor->refreshRate, pMonitor->scale, (int)pMonitor->transform, (int)pMonitor->vecPosition.x, (int)pMonitor->vecPosition.y,
|
||||||
(int)pMonitor->enabled10bit);
|
(int)pMonitor->enabled10bit);
|
||||||
|
|
||||||
|
g_pXWaylandManager->updateXWaylandScale();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue