This commit is contained in:
jschall 2025-12-31 23:09:46 -05:00 committed by GitHub
commit 91cc9527eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 142 additions and 6 deletions

View File

@ -292,7 +292,8 @@ export default class BreezyDesktopExtension extends Extension {
'display-size',
'framerate-cap',
'look-ahead-override',
'disable-anti-aliasing'
'disable-anti-aliasing',
'display-dimming'
]
this._effect_settings_bindings.forEach(settings_key =>
this.settings.bind(settings_key, this._virtual_displays_actor, settings_key, Gio.SettingsBindFlags.DEFAULT)

View File

@ -242,6 +242,15 @@ export const VirtualDisplayEffect = GObject.registerClass({
45,
-1
),
'display-dimming': GObject.ParamSpec.double(
'display-dimming',
'Display dimming',
'Dim the display brightness (0.0 to 1.0)',
GObject.ParamFlags.READWRITE,
0.0,
1.0,
1.0
),
}
}, class VirtualDisplayEffect extends Shell.GLSLEffect {
constructor(params = {}) {
@ -257,6 +266,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
this.connect('notify::monitor-placements', this._update_display_position.bind(this));
this.connect('notify::show-banner', this._handle_banner_update.bind(this));
this.connect('notify::smooth-follow-enabled', this._handle_smooth_follow_enabled_update.bind(this));
this.connect('notify::display-dimming', this._handle_dimming_update.bind(this));
this._update_display_position();
}
@ -402,6 +412,12 @@ export const VirtualDisplayEffect = GObject.registerClass({
this.set_uniform_float(this.get_uniform_location("u_show_banner"), 1, [this.show_banner ? 1.0 : 0.0]);
}
_handle_dimming_update() {
if (this._initialized) {
this.set_uniform_float(this.get_uniform_location("u_display_dimming"), 1, [this.display_dimming]);
}
}
perspective(fovHorizontalRadians, aspect, near, far) {
const f = 1.0 / Math.tan(fovHorizontalRadians / 2.0);
const range = far - near;
@ -538,6 +554,15 @@ export const VirtualDisplayEffect = GObject.registerClass({
`
this.add_glsl_snippet(Cogl.SnippetHook?.VERTEX ?? Shell.SnippetHook.VERTEX, declarations, main, false);
// Fragment shader for dimming
const fragmentDeclarations = `
uniform float u_display_dimming;
`;
const fragmentMain = `
cogl_color_out.rgb *= u_display_dimming;
`;
this.add_glsl_snippet(Cogl.SnippetHook?.FRAGMENT ?? Shell.SnippetHook.FRAGMENT, fragmentDeclarations, fragmentMain, false);
}
vfunc_paint_target(node, paintContext) {
@ -561,6 +586,7 @@ export const VirtualDisplayEffect = GObject.registerClass({
this.set_uniform_float(this.get_uniform_location("u_lens_vector"), 3, this.lens_vector);
this._update_display_position();
this._handle_banner_update();
this._handle_dimming_update();
}
if (this.imu_snapshots && !this.show_banner) {

View File

@ -572,6 +572,15 @@ export const VirtualDisplaysActor = GObject.registerClass({
'Disable anti-aliasing for the effect',
GObject.ParamFlags.READWRITE,
false
),
'display-dimming': GObject.ParamSpec.double(
'display-dimming',
'Display dimming',
'Dim the display brightness (0.0 to 1.0)',
GObject.ParamFlags.READWRITE,
0.0,
1.0,
1.0
)
}
}, class VirtualDisplaysActor extends Clutter.Actor {
@ -743,7 +752,8 @@ export const VirtualDisplaysActor = GObject.registerClass({
'lens-vector',
'look-ahead-override',
'disable-anti-aliasing',
'show-banner'
'show-banner',
'display-dimming'
].forEach((property => {
this._property_bindings.push(this.bind_property(property, effect, property, GObject.BindingFlags.DEFAULT));
}));

View File

@ -91,5 +91,12 @@
<label>Curved display</label>
<description>Curve the displays around you</description>
</entry>
<entry name="DisplayDimming" type="Int">
<default>100</default>
<min>0</min>
<max>100</max>
<label>Display Dimming</label>
<description>Dim the display brightness (0-100%)</description>
</entry>
</group>
</kcfg>

View File

@ -265,6 +265,9 @@ void BreezyDesktopEffect::reconfigure(ReconfigureFlags)
bool curved = BreezyDesktopConfig::curvedDisplay() && m_curvedDisplaySupported;
if (m_curvedDisplay != curved) { m_curvedDisplay = curved; Q_EMIT curvedDisplayChanged(); }
qreal dimming = BreezyDesktopConfig::displayDimming() / 100.0;
if (!qFuzzyCompare(m_displayDimming, dimming)) { m_displayDimming = dimming; Q_EMIT displayDimmingChanged(); }
// this one doesn't have a signal, just always assign it
m_allDisplaysFollowMode = BreezyDesktopConfig::allDisplaysFollowMode();
}
@ -563,6 +566,10 @@ bool BreezyDesktopEffect::curvedDisplaySupported() const {
return m_curvedDisplaySupported;
}
qreal BreezyDesktopEffect::displayDimming() const {
return m_displayDimming;
}
void BreezyDesktopEffect::setCurvedDisplaySupported(bool supported) {
if (m_curvedDisplaySupported != supported) {
m_curvedDisplaySupported = supported;

View File

@ -52,6 +52,7 @@ namespace KWin
Q_PROPERTY(bool mirrorPhysicalDisplays READ mirrorPhysicalDisplays NOTIFY mirrorPhysicalDisplaysChanged)
Q_PROPERTY(bool curvedDisplay READ curvedDisplay NOTIFY curvedDisplayChanged)
Q_PROPERTY(bool curvedDisplaySupported READ curvedDisplaySupported WRITE setCurvedDisplaySupported NOTIFY curvedDisplaySupportedChanged)
Q_PROPERTY(qreal displayDimming READ displayDimming NOTIFY displayDimmingChanged)
public:
@ -103,6 +104,7 @@ namespace KWin
bool mirrorPhysicalDisplays() const;
bool curvedDisplay() const;
void setCurvedDisplaySupported(bool supported);
qreal displayDimming() const;
void showCursor();
void hideCursor();
@ -142,6 +144,7 @@ namespace KWin
void curvedDisplaySupportedChanged();
void cursorImageSourceChanged();
void cursorPosChanged();
void displayDimmingChanged();
protected:
QVariantMap initialProperties(Output *screen) override;
@ -199,6 +202,7 @@ namespace KWin
bool m_mirrorPhysicalDisplays = false;
bool m_curvedDisplay = false;
bool m_curvedDisplaySupported = false;
qreal m_displayDimming = 1.0;
float m_smoothFollowThreshold = 1.0f;
bool m_allDisplaysFollowMode = false;
bool m_focusedSmoothFollowEnabled = false;

View File

@ -196,7 +196,36 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="8" column="0">
<widget class="QLabel" name="labelDisplayDimming">
<property name="text">
<string>Display brightness:</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="LabeledSlider" name="kcfg_DisplayDimming">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
<property name="tickStartOffset">
<double>0</double>
</property>
<property name="tickInterval">
<double>25</double>
</property>
<property name="suffix">
<string>%</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="labelVirtualDisplays">
<property name="text">
<string>Add Virtual Display:</string>
@ -209,7 +238,7 @@
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QWidget" name="widgetVirtualDisplayButtons">
<property name="visible">
<bool>false</bool>
@ -272,7 +301,7 @@
</layout>
</widget>
</item>
<item row="9" column="0" colspan="2">
<item row="10" column="0" colspan="2">
<widget class="QWidget" name="widgetVirtualDisplayList">
<property name="visible"><bool>false</bool></property>
<property name="enabled"><bool>false</bool></property>
@ -285,7 +314,7 @@
</layout>
</widget>
</item>
<item row="10" column="0" colspan="2">
<item row="11" column="0" colspan="2">
<widget class="KShortcutsEditor" name="shortcutsEditor" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">

View File

@ -57,6 +57,7 @@ Model {
property real cursorW: display.cursorImageSize.width
property real cursorH: display.cursorImageSize.height
property bool showCursor: cursorX >= 0 && cursorX < screenWidth && cursorY >= 0 && cursorY < screenHeight
property real displayDimming: effect.displayDimming
property TextureInput desktopTex: TextureInput {
texture: Texture {

View File

@ -14,5 +14,7 @@ void MAIN() {
color = mix(color, cursorCol, cursorCol.a);
}
}
// Apply dimming by scaling RGB towards black while preserving alpha
color.rgb *= displayDimming;
FRAGCOLOR = color;
}

View File

@ -279,6 +279,15 @@
<description>
Framerate cap
</description>
</key>
<key name="display-dimming" type="d">
<default>
1.0
</default>
<summary>Display dimming</summary>
<description>
Dim the display brightness (0.0 to 1.0)
</description>
</key>
</schema>
</schemalist>

View File

@ -35,6 +35,8 @@ class ConnectedDevice(Gtk.Box):
display_zoom_on_focus_switch = Gtk.Template.Child()
follow_threshold_scale = Gtk.Template.Child()
follow_threshold_adjustment = Gtk.Template.Child()
display_dimming_scale = Gtk.Template.Child()
display_dimming_adjustment = Gtk.Template.Child()
follow_mode_switch = Gtk.Template.Child()
curved_display_switch = Gtk.Template.Child()
top_features_group = Gtk.Template.Child()
@ -130,6 +132,10 @@ class ConnectedDevice(Gtk.Box):
self.settings.bind('monitor-spacing', self.monitor_spacing_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
self.settings.bind('viewport-offset-x', self.viewport_offset_x_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
self.settings.bind('viewport-offset-y', self.viewport_offset_y_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
# Display dimming uses 0-100 in UI but 0.0-1.0 in settings
self.display_dimming_adjustment.set_value(self.settings.get_double('display-dimming') * 100)
self.display_dimming_adjustment.connect('value-changed', self._on_display_dimming_changed)
self.settings.connect('changed::monitor-wrapping-scheme', self._handle_monitor_wrapping_scheme_setting_changed)
self.desktop_settings.bind('text-scaling-factor', self.text_scaling_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
self.display_zoom_on_focus_switch.connect('notify::active', self._handle_zoom_on_focus_switch_changed)
@ -244,6 +250,9 @@ class ConnectedDevice(Gtk.Box):
def _handle_monitor_wrapping_scheme_menu_changed(self, widget):
self.settings.set_string('monitor-wrapping-scheme', widget.get_active_id())
def _on_display_dimming_changed(self, adjustment):
self.settings.set_double('display-dimming', adjustment.get_value() / 100.0)
def _handle_enabled_features(self, state_manager, val):
enabled_breezy_features = [feature for feature in state_manager.get_property('enabled-features-list') if feature in BREEZY_GNOME_FEATURES]
breezy_features_granted = len(enabled_breezy_features) > 0

View File

@ -253,6 +253,37 @@
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes"><!-- adjustment slider -->Display brightness</property>
<property name="subtitle" translatable="yes">Dim the display to reduce eye strain or match ambient lighting.</property>
<child>
<object class="GtkScale" id="display_dimming_scale">
<property name="valign">3</property>
<property name="draw-value">true</property>
<property name="value-pos">0</property>
<property name="digits">0</property>
<property name="width-request">350</property>
<property name="has-origin">false</property>
<property name="adjustment">
<object class="GtkAdjustment" id="display_dimming_adjustment">
<property name="lower">0</property>
<property name="upper">100</property>
<property name="step-increment">1</property>
<property name="value">100</property>
</object>
</property>
<marks>
<mark value="0" position="bottom">0%</mark>
<mark value="25" position="bottom"></mark>
<mark value="50" position="bottom">50%</mark>
<mark value="75" position="bottom"></mark>
<mark value="100" position="bottom">100%</mark>
</marks>
</object>
</child>
</object>
</child>
<child>
<object class="AdwActionRow">
<property name="title" translatable="yes"><!-- dropdown menu -->Display angling</property>