Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion gnome/src/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 26 additions & 0 deletions gnome/src/virtualdisplayeffect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}) {
Expand All @@ -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();
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
`;
Comment on lines +562 to +564

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be more appropriate to adjust the alpha layer?

this.add_glsl_snippet(Cogl.SnippetHook?.FRAGMENT ?? Shell.SnippetHook.FRAGMENT, fragmentDeclarations, fragmentMain, false);
}

vfunc_paint_target(node, paintContext) {
Expand All @@ -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) {
Expand Down
12 changes: 11 additions & 1 deletion gnome/src/virtualdisplaysactor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
}));
Expand Down
7 changes: 7 additions & 0 deletions kwin/src/breezydesktopconfig.kcfg
Original file line number Diff line number Diff line change
Expand Up @@ -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>
7 changes: 7 additions & 0 deletions kwin/src/breezydesktopeffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions kwin/src/breezydesktopeffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -103,6 +104,7 @@ namespace KWin
bool mirrorPhysicalDisplays() const;
bool curvedDisplay() const;
void setCurvedDisplaySupported(bool supported);
qreal displayDimming() const;

void showCursor();
void hideCursor();
Expand Down Expand Up @@ -142,6 +144,7 @@ namespace KWin
void curvedDisplaySupportedChanged();
void cursorImageSourceChanged();
void cursorPosChanged();
void displayDimmingChanged();

protected:
QVariantMap initialProperties(Output *screen) override;
Expand Down Expand Up @@ -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;
Expand Down
37 changes: 33 additions & 4 deletions kwin/src/kcm/breezydesktopeffectkcm.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand All @@ -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">
Expand Down
1 change: 1 addition & 0 deletions kwin/src/qml/BreezyDesktopDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions kwin/src/qml/cursorOverlay.frag
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
9 changes: 9 additions & 0 deletions ui/data/com.xronlinux.BreezyDesktop.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
9 changes: 9 additions & 0 deletions ui/src/connecteddevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -130,6 +132,10 @@ def __init__(self):
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)

Copilot AI Jan 2, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is inconsistent whitespace formatting - a trailing whitespace exists on this otherwise empty line. This should be removed to maintain code cleanliness and consistency with project standards.

Suggested change

Copilot uses AI. Check for mistakes.
# 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)
Expand Down Expand Up @@ -244,6 +250,9 @@ def _handle_monitor_wrapping_scheme_setting_changed(self, settings, val):
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
Expand Down
31 changes: 31 additions & 0 deletions ui/src/gtk/connected-device.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down