From 45294acc77e2bc699314608802e960cd60638280 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 8 Oct 2021 14:57:44 -0700 Subject: [PATCH] feat: Add toggle for vertical workspaces This adds a toggle for enabling/disabling vertical workspaces on Gnome 40. We've mentioned supporting it. If we're satisfied with just enabling/disabling the vertical-overview extension (as done here), it's not too hard to support. Though we will want to test that Cosmic works well with or without it enabled. Not sure if there's a better UI for this. --- i18n/en/pop_desktop_widget.ftl | 1 + src/lib.rs | 53 +++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/i18n/en/pop_desktop_widget.ftl b/i18n/en/pop_desktop_widget.ftl index 27e4e16..ae00603 100644 --- a/i18n/en/pop_desktop_widget.ftl +++ b/i18n/en/pop_desktop_widget.ftl @@ -62,6 +62,7 @@ page-dock = Dock page-main = General page-workspaces = Workspaces +vertical-workspaces = Vertical workspaces in overview position-bottom = Bottom of the screen position-left = Along the left side position-right = Along the right side diff --git a/src/lib.rs b/src/lib.rs index cef1ef2..5de75f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,13 +15,16 @@ use gtk_extras::settings; use i18n_embed::DesktopLanguageRequester; use libhandy::prelude::*; use pop_theme_switcher::PopThemeSwitcher; -use std::{cell::RefCell, rc::Rc}; +use std::{cell::RefCell, path::Path, rc::Rc}; const PAGE_APPEARANCE: &str = "appearance"; const PAGE_DOCK: &str = "dock"; const PAGE_MAIN: &str = "main"; const PAGE_WORKSPACES: &str = "workspaces"; +const EXTENSIONS_DIR: &str = "/usr/share/gnome-shell/extensions/"; +const VERTICAL_OVERVIEW_EXT: &str = "vertical-overview@RensAlthuis.github.com"; + pub fn localize() { let localizer = crate::localize::localizer(); let requested_languages = DesktopLanguageRequester::requested_languages(); @@ -44,6 +47,17 @@ fn header_func(row: >k::ListBoxRow, before: Option<>k::ListBoxRow>) { } } +// Set add/remove operation, on a Vec +fn vec_add_remove(vec: &mut Vec, item: T, add: bool) { + if let Some(position) = vec.iter().position(|x| x == &item) { + if !add { + vec.remove(position); + } + } else if add { + vec.push(item); + } +} + fn combo_row( container: &C, title: &str, @@ -725,9 +739,46 @@ fn workspaces_position(container: &C) { let list_box = settings_list_box(container, &fl!("workspace-picker-position")); + let switch = if Path::new(&format!("{}{}", EXTENSIONS_DIR, VERTICAL_OVERVIEW_EXT)).exists() { + let shell_settings = gio::Settings::new("org.gnome.shell"); + let switch = switch_row(&list_box, &fl!("vertical-workspaces")); + + // Extension is enabled if in `enabled-extensions` but not `disabled-extensions` + let enabled = shell_settings.get_strv("enabled-extensions"); + let disabled = shell_settings.get_strv("disabled-extensions"); + let active = enabled.iter().find(|x| *x == VERTICAL_OVERVIEW_EXT).is_some() && + !disabled.iter().find(|x| *x == VERTICAL_OVERVIEW_EXT).is_some(); + switch.set_active(active); + + switch.connect_property_active_notify(move |switch| { + // Add/remove from `enabled-extensions` + let enabled = shell_settings.get_strv("enabled-extensions"); + let mut enabled = enabled.iter().map(|x| x.as_str()).collect::>(); + vec_add_remove(&mut enabled, VERTICAL_OVERVIEW_EXT, switch.get_active()); + shell_settings.set_strv("enabled-extensions", &enabled).unwrap(); + + // Add/remove from `disabled-extensions` + let disabled = shell_settings.get_strv("disabled-extensions"); + let mut disabled = disabled.iter().map(|x| x.as_str()).collect::>(); + vec_add_remove(&mut disabled, VERTICAL_OVERVIEW_EXT, !switch.get_active()); + shell_settings.set_strv("disabled-extensions", &disabled).unwrap(); + }); + + Some(switch) + } else { + None + }; + let radio_left = radio_row(&list_box, &fl!("position-left"), None); let radio_right = radio_row(&list_box, &fl!("position-right"), None); radio_right.join_group(Some(&radio_left)); + + if let Some(switch) = switch { + list_box.get_children().iter().rev().take(2).for_each(|row| { + switch.bind_property("active", row, "sensitive").flags(glib::BindingFlags::SYNC_CREATE).build(); + }); + } + radio_bindings( &settings, "workspace-picker-left",