Add curved display support
This commit is contained in:
parent
e395a0e2fc
commit
c2dfefd395
|
|
@ -86,5 +86,10 @@
|
|||
<label>All displays follow mode</label>
|
||||
<description>Apply follow mode to all displays instead of only the focused display</description>
|
||||
</entry>
|
||||
<entry name="CurvedDisplay" type="Bool">
|
||||
<default>false</default>
|
||||
<label>Curved display</label>
|
||||
<description>Curve the displays around you</description>
|
||||
</entry>
|
||||
</group>
|
||||
</kcfg>
|
||||
|
|
|
|||
|
|
@ -229,6 +229,9 @@ void BreezyDesktopEffect::reconfigure(ReconfigureFlags)
|
|||
if (m_removeVirtualDisplaysOnDisable != removeVD) { m_removeVirtualDisplaysOnDisable = removeVD; Q_EMIT removeVirtualDisplaysOnDisableChanged(); }
|
||||
if (m_mirrorPhysicalDisplays != mirrorPhysicalDisplays) { m_mirrorPhysicalDisplays = mirrorPhysicalDisplays; Q_EMIT mirrorPhysicalDisplaysChanged(); }
|
||||
|
||||
bool curved = BreezyDesktopConfig::curvedDisplay();
|
||||
if (m_curvedDisplay != curved) { m_curvedDisplay = curved; Q_EMIT curvedDisplayChanged(); }
|
||||
|
||||
// this one doesn't have a signal, just always assign it
|
||||
m_allDisplaysFollowMode = BreezyDesktopConfig::allDisplaysFollowMode();
|
||||
}
|
||||
|
|
@ -505,6 +508,10 @@ bool BreezyDesktopEffect::mirrorPhysicalDisplays() const {
|
|||
return m_mirrorPhysicalDisplays;
|
||||
}
|
||||
|
||||
bool BreezyDesktopEffect::curvedDisplay() const {
|
||||
return m_curvedDisplay;
|
||||
}
|
||||
|
||||
QList<QQuaternion> BreezyDesktopEffect::smoothFollowOrigin() const {
|
||||
return m_smoothFollowOrigin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ namespace KWin
|
|||
Q_PROPERTY(int antialiasingQuality READ antialiasingQuality NOTIFY antialiasingQualityChanged)
|
||||
Q_PROPERTY(bool removeVirtualDisplaysOnDisable READ removeVirtualDisplaysOnDisable NOTIFY removeVirtualDisplaysOnDisableChanged)
|
||||
Q_PROPERTY(bool mirrorPhysicalDisplays READ mirrorPhysicalDisplays NOTIFY mirrorPhysicalDisplaysChanged)
|
||||
Q_PROPERTY(bool curvedDisplay READ curvedDisplay NOTIFY curvedDisplayChanged)
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -87,6 +88,7 @@ namespace KWin
|
|||
int antialiasingQuality() const;
|
||||
bool removeVirtualDisplaysOnDisable() const;
|
||||
bool mirrorPhysicalDisplays() const;
|
||||
bool curvedDisplay() const;
|
||||
|
||||
void showCursor();
|
||||
void hideCursor();
|
||||
|
|
@ -120,6 +122,7 @@ namespace KWin
|
|||
void antialiasingQualityChanged();
|
||||
void removeVirtualDisplaysOnDisableChanged();
|
||||
void mirrorPhysicalDisplaysChanged();
|
||||
void curvedDisplayChanged();
|
||||
void cursorImageSourceChanged();
|
||||
void cursorPosChanged();
|
||||
|
||||
|
|
@ -167,6 +170,7 @@ namespace KWin
|
|||
int m_antialiasingQuality = 3; // 0=None, 1=Medium, 2=High, 3=VeryHigh
|
||||
bool m_removeVirtualDisplaysOnDisable = true;
|
||||
bool m_mirrorPhysicalDisplays = false;
|
||||
bool m_curvedDisplay = false;
|
||||
float m_smoothFollowThreshold = 1.0f;
|
||||
bool m_allDisplaysFollowMode = false;
|
||||
bool m_focusedSmoothFollowEnabled = false;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ BreezyDesktopEffectConfig::BreezyDesktopEffectConfig(QObject *parent, const KPlu
|
|||
connect(ui.kcfg_MirrorPhysicalDisplays, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::save);
|
||||
connect(ui.kcfg_RemoveVirtualDisplaysOnDisable, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::save);
|
||||
connect(ui.kcfg_AllDisplaysFollowMode, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::save);
|
||||
connect(ui.kcfg_CurvedDisplay, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::save);
|
||||
connect(ui.EnableMultitap, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::updateMultitapEnabled);
|
||||
connect(ui.SmoothFollowTrackYaw, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::updateSmoothFollowTrackYaw);
|
||||
connect(ui.SmoothFollowTrackPitch, &QCheckBox::toggled, this, &BreezyDesktopEffectConfig::updateSmoothFollowTrackPitch);
|
||||
|
|
@ -257,6 +258,7 @@ void BreezyDesktopEffectConfig::updateUiFromConfig()
|
|||
ui.kcfg_DisplayWrappingScheme->setCurrentIndex(BreezyDesktopConfig::self()->displayWrappingScheme());
|
||||
ui.kcfg_AntialiasingQuality->setCurrentIndex(BreezyDesktopConfig::self()->antialiasingQuality());
|
||||
ui.kcfg_MirrorPhysicalDisplays->setChecked(BreezyDesktopConfig::self()->mirrorPhysicalDisplays());
|
||||
ui.kcfg_CurvedDisplay->setChecked(BreezyDesktopConfig::self()->curvedDisplay());
|
||||
ui.kcfg_RemoveVirtualDisplaysOnDisable->setChecked(BreezyDesktopConfig::self()->removeVirtualDisplaysOnDisable());
|
||||
ui.kcfg_AllDisplaysFollowMode->setChecked(BreezyDesktopConfig::self()->allDisplaysFollowMode());
|
||||
ui.kcfg_ZoomOnFocusEnabled->setChecked(BreezyDesktopConfig::self()->zoomOnFocusEnabled());
|
||||
|
|
|
|||
|
|
@ -73,6 +73,16 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="kcfg_CurvedDisplay">
|
||||
<property name="text">
|
||||
<string>Curved display</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="SmoothFollowEnabled">
|
||||
<property name="text">
|
||||
<string>Follow mode</string>
|
||||
|
|
@ -82,14 +92,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelFocusedDisplayDistance">
|
||||
<property name="text">
|
||||
<string>Focused Display Distance:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="LabeledSlider" name="kcfg_FocusedDisplayDistance">
|
||||
<property name="decimalShift">
|
||||
<double>2</double>
|
||||
|
|
@ -111,14 +121,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelAllDisplaysDistance">
|
||||
<property name="text">
|
||||
<string>All Displays Distance:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="LabeledSlider" name="kcfg_AllDisplaysDistance">
|
||||
<property name="decimalShift">
|
||||
<double>2</double>
|
||||
|
|
@ -140,14 +150,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="labelDisplaySpacing">
|
||||
<property name="text">
|
||||
<string>Display Spacing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<widget class="QSlider" name="kcfg_DisplaySpacing">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
|
@ -157,14 +167,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="labelFollowThreshold">
|
||||
<property name="text">
|
||||
<string>Follow threshold:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="LabeledSlider" name="kcfg_SmoothFollowThreshold">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
|
@ -186,7 +196,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="labelVirtualDisplays">
|
||||
<property name="text">
|
||||
<string>Add Virtual Display:</string>
|
||||
|
|
@ -199,7 +209,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QWidget" name="widgetVirtualDisplayButtons">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
|
|
@ -232,7 +242,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widgetVirtualDisplayList">
|
||||
<property name="visible"><bool>false</bool></property>
|
||||
<property name="enabled"><bool>false</bool></property>
|
||||
|
|
@ -245,7 +255,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="KShortcutsEditor" name="shortcutsEditor" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ Node {
|
|||
delegate: BreezyDesktopDisplay {
|
||||
screen: breezyDesktop.screens[index]
|
||||
monitorPlacement: breezyDesktop.monitorPlacements[index]
|
||||
fovDetails: breezyDesktop.fovDetails
|
||||
|
||||
property real smoothFollowTransitionProgress: 0.0
|
||||
property real monitorDistance: effect.allDisplaysDistance
|
||||
|
|
@ -158,14 +159,6 @@ Node {
|
|||
return matrix;
|
||||
}
|
||||
|
||||
property vector3d screenScale: {
|
||||
const geometry = screen.geometry;
|
||||
|
||||
// apparently the default model unit size is 100x100, so we scale it up to the screen size
|
||||
return Qt.vector3d(geometry.width / 100, geometry.height / 100, 1);
|
||||
}
|
||||
|
||||
scale: screenScale
|
||||
eulerRotation.y: screenRotationY
|
||||
eulerRotation.x: screenRotationX
|
||||
position: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick
|
||||
import QtQuick3D
|
||||
import QtQuick3D.Helpers
|
||||
|
||||
Model {
|
||||
id: display
|
||||
|
|
@ -7,12 +8,107 @@ Model {
|
|||
required property QtObject screen
|
||||
required property var monitorPlacement
|
||||
required property int index
|
||||
required property var fovDetails
|
||||
|
||||
property string cursorImageSource: effect.cursorImageSource
|
||||
property size cursorImageSize: effect.cursorImageSize
|
||||
property point cursorPos: effect.cursorPos
|
||||
|
||||
source: "#Rectangle"
|
||||
Displays {
|
||||
id: displays
|
||||
}
|
||||
|
||||
geometry: ProceduralMesh {
|
||||
id: mesh
|
||||
|
||||
property var _meshArrays: generateMesh()
|
||||
positions: _meshArrays.positions
|
||||
uv0s: _meshArrays.uvs
|
||||
indexes: _meshArrays.indices
|
||||
primitiveMode: ProceduralMesh.TriangleStrip
|
||||
|
||||
function generateMesh() {
|
||||
if (!display.fovDetails || !display.screen)
|
||||
return { positions: [], uvs: [], indices: [] };
|
||||
|
||||
const fov = display.fovDetails;
|
||||
const monitor = display.screen.geometry;
|
||||
|
||||
const conv = fov.curvedDisplay ? displays.fovConversionFns.curved
|
||||
: displays.fovConversionFns.flat;
|
||||
|
||||
const horizontalWrap = fov.monitorWrappingScheme === 'horizontal';
|
||||
const verticalWrap = fov.monitorWrappingScheme === 'vertical';
|
||||
|
||||
const sideEdgeDistance = conv.centerToFovEdgeDistance(
|
||||
fov.completeScreenDistancePixels, fov.widthPixels);
|
||||
const horizontalRadians = conv.lengthToRadians(
|
||||
fov.defaultDistanceHorizontalRadians,
|
||||
fov.widthPixels,
|
||||
sideEdgeDistance,
|
||||
monitor.width
|
||||
);
|
||||
|
||||
const topEdgeDistance = conv.centerToFovEdgeDistance(
|
||||
fov.completeScreenDistancePixels, fov.heightPixels);
|
||||
const verticalRadians = conv.lengthToRadians(
|
||||
fov.defaultDistanceVerticalRadians,
|
||||
fov.heightPixels,
|
||||
topEdgeDistance,
|
||||
monitor.height
|
||||
);
|
||||
|
||||
const positions = [];
|
||||
const uvs = [];
|
||||
const indices = [];
|
||||
|
||||
const radius = fov.completeScreenDistancePixels;
|
||||
function vertexFor(s, t) {
|
||||
let z = 0;
|
||||
|
||||
const xOffset = s - 0.5;
|
||||
let x = xOffset * monitor.width;
|
||||
if (fov.curvedDisplay && horizontalWrap) {
|
||||
const xOffsetRadians = xOffset * horizontalRadians;
|
||||
x = Math.sin(xOffsetRadians) * radius;
|
||||
z = radius - Math.cos(xOffsetRadians) * radius;
|
||||
}
|
||||
|
||||
const yOffset = t - 0.5;
|
||||
let y = yOffset * monitor.height;
|
||||
if (fov.curvedDisplay && verticalWrap) {
|
||||
const yOffsetRadians = yOffset * verticalRadians;
|
||||
y = Math.sin(yOffsetRadians) * radius;
|
||||
z = radius - Math.cos(yOffsetRadians) * radius;
|
||||
}
|
||||
|
||||
return { pos: Qt.vector3d(x, y, z), uv: Qt.vector2d(s, t) };
|
||||
}
|
||||
|
||||
let segments = 1;
|
||||
if (horizontalWrap) segments = conv.radiansToSegments(horizontalRadians);
|
||||
if (verticalWrap) segments = conv.radiansToSegments(verticalRadians);
|
||||
for (let i = 0; i <= segments; i++) {
|
||||
const texFraction = i / segments;
|
||||
|
||||
// !verticalWrap also covers "flat" wrap scheme
|
||||
const texX0 = !verticalWrap ? texFraction : 0;
|
||||
const texX1 = !verticalWrap ? texFraction : 1;
|
||||
|
||||
const texY0 = verticalWrap ? texFraction : 1;
|
||||
const texY1 = verticalWrap ? texFraction : 0;
|
||||
|
||||
let vtxB = vertexFor(texX0, texY0);
|
||||
let vtxT = vertexFor(texX1, texY1);
|
||||
positions.push(vtxB.pos);
|
||||
positions.push(vtxT.pos);
|
||||
uvs.push(vtxB.uv);
|
||||
uvs.push(vtxT.uv);
|
||||
}
|
||||
|
||||
return { positions: positions, uvs: uvs, indices: [] };
|
||||
}
|
||||
}
|
||||
materials: [
|
||||
CustomMaterial {
|
||||
id: customMat
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ QtObject {
|
|||
lensDistancePixels,
|
||||
completeScreenDistancePixels,
|
||||
monitorWrappingScheme: monitorWrappingScheme,
|
||||
curvedDisplay: false // or true
|
||||
curvedDisplay: effect.curvedDisplay
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue