Skip to content

Commit 6315621

Browse files
committed
Linux: query dconf for CSD position (left/right)
Instead of making users specify their preference for Zed in settings.json, read the system preference. Fixes #14120
1 parent 772cac4 commit 6315621

File tree

7 files changed

+139
-37
lines changed

7 files changed

+139
-37
lines changed

Cargo.lock

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/settings/src/settings_content.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -234,23 +234,6 @@ pub enum BaseKeymapContent {
234234
None,
235235
}
236236

237-
/// Position of window control buttons on Linux.
238-
///
239-
/// Valid values: "left" or "right"
240-
/// - "left": Window controls on the left side (macOS style)
241-
/// - "right": Window controls on the right side (Windows style)
242-
#[derive(
243-
Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, Default,
244-
)]
245-
#[serde(rename_all = "snake_case")]
246-
pub enum WindowControlsPosition {
247-
/// Window controls on the left side (macOS style)
248-
Left,
249-
/// Window controls on the right side (Windows style)
250-
#[default]
251-
Right,
252-
}
253-
254237
#[skip_serializing_none]
255238
#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, MergeFrom, Debug)]
256239
pub struct TitleBarSettingsContent {
@@ -282,10 +265,6 @@ pub struct TitleBarSettingsContent {
282265
///
283266
/// Default: false
284267
pub show_menus: Option<bool>,
285-
/// Position of window control buttons (minimize, maximize, close) on Linux.
286-
///
287-
/// Default: right
288-
pub window_controls_position: Option<WindowControlsPosition>,
289268
}
290269

291270
/// Configuration of audio in Zed.

crates/title_bar/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ workspace-hack.workspace = true
5555
[target.'cfg(windows)'.dependencies]
5656
windows.workspace = true
5757

58+
[target.'cfg(target_os = "linux")'.dependencies]
59+
dconf = "0.1.1"
60+
5861
[dev-dependencies]
5962
call = { workspace = true, features = ["test-support"] }
6063
client = { workspace = true, features = ["test-support"] }

crates/title_bar/src/platform_title_bar.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use crate::title_bar_settings::TitleBarSettings;
1+
use crate::WindowControlsPosition;
22
use gpui::{
33
AnyElement, Context, Decorations, Entity, Hsla, InteractiveElement, IntoElement, MouseButton,
44
ParentElement, Pixels, StatefulInteractiveElement, Styled, Window, WindowControlArea, div, px,
55
};
6-
use settings::{Settings, WindowControlsPosition};
76
use smallvec::SmallVec;
87
use std::mem;
98
use ui::prelude::*;
@@ -19,19 +18,37 @@ pub struct PlatformTitleBar {
1918
children: SmallVec<[AnyElement; 2]>,
2019
should_move: bool,
2120
system_window_tabs: Entity<SystemWindowTabs>,
21+
window_controls_position: WindowControlsPosition,
2222
}
2323

2424
impl PlatformTitleBar {
2525
pub fn new(id: impl Into<ElementId>, cx: &mut Context<Self>) -> Self {
2626
let platform_style = PlatformStyle::platform();
2727
let system_window_tabs = cx.new(|_cx| SystemWindowTabs::new());
28+
let window_controls_position = if cfg!(target_os = "linux") {
29+
if let Ok(Some(value)) =
30+
dconf::read_string("/org/gnome/desktop/wm/preferences/button-layout")
31+
{
32+
// This is the value that GNOME Tweaks sets when setting window button position to left.
33+
if value == "close,minimize,maximize:icon" {
34+
WindowControlsPosition::Left
35+
} else {
36+
WindowControlsPosition::Right
37+
}
38+
} else {
39+
WindowControlsPosition::Right
40+
}
41+
} else {
42+
WindowControlsPosition::Right
43+
};
2844

2945
Self {
3046
id: id.into(),
3147
platform_style,
3248
children: SmallVec::new(),
3349
should_move: false,
3450
system_window_tabs,
51+
window_controls_position,
3552
}
3653
}
3754

@@ -112,8 +129,7 @@ impl Render for PlatformTitleBar {
112129
.items_center()
113130
.map(|this| {
114131
if self.platform_style == PlatformStyle::Linux {
115-
let title_bar_settings = TitleBarSettings::get(None, cx);
116-
match title_bar_settings.window_controls_position {
132+
match self.window_controls_position {
117133
WindowControlsPosition::Left => this.justify_start(),
118134
WindowControlsPosition::Right => this.justify_between(),
119135
}
@@ -144,15 +160,15 @@ impl Render for PlatformTitleBar {
144160
PlatformStyle::Mac => title_bar,
145161
PlatformStyle::Linux => {
146162
if matches!(decorations, Decorations::Client { .. }) {
147-
let title_bar_settings = TitleBarSettings::get(None, cx);
148-
match title_bar_settings.window_controls_position {
163+
match self.window_controls_position {
149164
WindowControlsPosition::Left => {
150165
// macOS style: controls at the beginning of the title bar
151166
h_flex()
152167
.w_full()
153168
.bg(titlebar_color)
154169
.child(platform_linux::LinuxWindowControls::new(
155170
close_action,
171+
WindowControlsPosition::Left,
156172
))
157173
.child(title_bar)
158174
.when(supported_controls.window_menu, |titlebar| {
@@ -192,6 +208,7 @@ impl Render for PlatformTitleBar {
192208
title_bar
193209
.child(platform_linux::LinuxWindowControls::new(
194210
close_action,
211+
WindowControlsPosition::Right,
195212
))
196213
.when(supported_controls.window_menu, |titlebar| {
197214
titlebar.on_mouse_down(

crates/title_bar/src/platforms/platform_linux.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
1-
use crate::title_bar_settings::TitleBarSettings;
1+
use crate::WindowControlsPosition;
22
use gpui::{Action, Hsla, MouseButton, prelude::*, svg};
3-
use settings::{Settings, WindowControlsPosition};
43
use ui::prelude::*;
54

65
#[derive(IntoElement)]
76
pub struct LinuxWindowControls {
87
close_window_action: Box<dyn Action>,
8+
window_controls_position: WindowControlsPosition,
99
}
1010

1111
impl LinuxWindowControls {
12-
pub fn new(close_window_action: Box<dyn Action>) -> Self {
12+
pub fn new(
13+
close_window_action: Box<dyn Action>,
14+
window_controls_position: WindowControlsPosition,
15+
) -> Self {
1316
Self {
1417
close_window_action,
18+
window_controls_position,
1519
}
1620
}
1721
}
1822

1923
impl LinuxWindowControls {
2024
/// Builds the window controls based on the position setting.
2125
fn build_controls(
22-
position: WindowControlsPosition,
2326
window: &Window,
2427
close_action: Box<dyn Action>,
28+
window_controls_position: WindowControlsPosition,
2529
cx: &mut App,
2630
) -> Vec<WindowControl> {
2731
let maximize_type = if window.is_maximized() {
@@ -30,7 +34,7 @@ impl LinuxWindowControls {
3034
WindowControlType::Maximize
3135
};
3236

33-
match position {
37+
match window_controls_position {
3438
WindowControlsPosition::Left => {
3539
// Left side: Close, Minimize, Maximize (left to right)
3640
vec![
@@ -53,11 +57,10 @@ impl LinuxWindowControls {
5357

5458
impl RenderOnce for LinuxWindowControls {
5559
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
56-
let title_bar_settings = TitleBarSettings::get(None, cx);
5760
let controls = Self::build_controls(
58-
title_bar_settings.window_controls_position,
5961
window,
6062
self.close_window_action,
63+
self.window_controls_position,
6164
cx,
6265
);
6366

crates/title_bar/src/title_bar.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ actions!(
6565
]
6666
);
6767

68+
pub(crate) enum WindowControlsPosition {
69+
Left,
70+
Right,
71+
}
72+
6873
pub fn init(cx: &mut App) {
6974
TitleBarSettings::register(cx);
7075
SystemWindowTabs::init(cx);

crates/title_bar/src/title_bar_settings.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use settings::{Settings, SettingsContent, WindowControlsPosition};
1+
use settings::{Settings, SettingsContent};
22
use ui::App;
33

44
#[derive(Copy, Clone, Debug)]
@@ -10,7 +10,6 @@ pub struct TitleBarSettings {
1010
pub show_project_items: bool,
1111
pub show_sign_in: bool,
1212
pub show_menus: bool,
13-
pub window_controls_position: WindowControlsPosition,
1413
}
1514

1615
impl Settings for TitleBarSettings {
@@ -24,7 +23,6 @@ impl Settings for TitleBarSettings {
2423
show_project_items: content.show_project_items.unwrap(),
2524
show_sign_in: content.show_sign_in.unwrap(),
2625
show_menus: content.show_menus.unwrap(),
27-
window_controls_position: content.window_controls_position.unwrap_or_default(),
2826
}
2927
}
3028
}

0 commit comments

Comments
 (0)