From 8cf3485ab0acec04c541dd9ba984e88f7a192d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Mon, 2 Aug 2021 18:22:46 +0200 Subject: [PATCH] monitor-manager: Notify privacy screen changes on hotkey press When privacy screen is changed and this happens on explicit user request (that is not a setting change) we should notify about this via an OSD. To perform this, we keep track of the reason that lead to a privacy screen change, and when we record it we try to notify the user about. When the hardware has not an explicit hotkey signal but we record a change we must still fallback to this case. Fixes: #2105 Part-of: --- src/backends/meta-monitor-manager-private.h | 13 ++++ src/backends/meta-monitor-manager.c | 64 ++++++++++++++++++- src/backends/meta-settings-private.h | 3 + src/backends/meta-settings.c | 12 ++++ .../native/meta-monitor-manager-native.c | 25 +++++++- src/core/display.c | 22 +++++++ 6 files changed, 135 insertions(+), 4 deletions(-) diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h index abf63ce51..443ad14cd 100644 --- a/src/backends/meta-monitor-manager-private.h +++ b/src/backends/meta-monitor-manager-private.h @@ -35,6 +35,7 @@ #include "backends/meta-viewport-info.h" #include "core/util-private.h" #include "meta/display.h" +#include "meta/meta-enum-types.h" #include "meta/meta-monitor-manager.h" #define META_MONITOR_MANAGER_MIN_SCREEN_WIDTH 640 @@ -62,6 +63,14 @@ typedef enum _MetaLogicalMonitorLayoutMode META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2 } MetaLogicalMonitorLayoutMode; +/* The source the privacy screen change has been triggered */ +typedef enum +{ + META_PRIVACY_SCREEN_CHANGE_STATE_NONE, + META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_HOTKEY, + META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING, +} MetaPrivacyScreenChangeState; + /* * MetaCrtcAssignment: * @@ -149,6 +158,8 @@ struct _MetaMonitorManager GnomePnpIds *pnp_ids; MetaMonitorSwitchConfigType current_switch_config; + + MetaPrivacyScreenChangeState privacy_screen_change_state; }; /** @@ -440,4 +451,6 @@ MetaViewportInfo * meta_monitor_manager_get_viewports (MetaMonitorManager *manag GList * meta_monitor_manager_get_virtual_monitors (MetaMonitorManager *manager); +void meta_monitor_manager_maybe_emit_privacy_screen_change (MetaMonitorManager *manager); + #endif /* META_MONITOR_MANAGER_PRIVATE_H */ diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c index 2dff6539e..3b650c62c 100644 --- a/src/backends/meta-monitor-manager.c +++ b/src/backends/meta-monitor-manager.c @@ -83,6 +83,7 @@ enum MONITORS_CHANGED_INTERNAL, POWER_SAVE_MODE_CHANGED, CONFIRM_DISPLAY_CHANGE, + MONITOR_PRIVACY_SCREEN_CHANGED, SIGNALS_LAST }; @@ -1092,7 +1093,11 @@ apply_privacy_screen_settings (MetaMonitorManager *manager) meta_settings_is_privacy_screen_enabled (settings)) return; - ensure_monitors_settings (manager); + if (ensure_monitors_settings (manager)) + { + manager->privacy_screen_change_state = + META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING; + } } static void @@ -1354,6 +1359,14 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass) NULL, NULL, NULL, G_TYPE_NONE, 0); + signals[MONITOR_PRIVACY_SCREEN_CHANGED] = + g_signal_new ("monitor-privacy-screen-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, NULL, + G_TYPE_NONE, 2, META_TYPE_LOGICAL_MONITOR, G_TYPE_BOOLEAN); + obj_props[PROP_BACKEND] = g_param_spec_object ("backend", "backend", @@ -1446,6 +1459,55 @@ combine_gpu_lists (MetaMonitorManager *manager, return list; } +static void +emit_privacy_screen_change (MetaMonitorManager *manager) +{ + GList *l; + + for (l = manager->monitors; l; l = l->next) + { + MetaMonitor *monitor = l->data; + MetaPrivacyScreenState privacy_screen_state; + gboolean enabled; + + if (!meta_monitor_is_active (monitor)) + continue; + + privacy_screen_state = meta_monitor_get_privacy_screen_state (monitor); + if (privacy_screen_state == META_PRIVACY_SCREEN_UNAVAILABLE) + continue; + + enabled = !!(privacy_screen_state & META_PRIVACY_SCREEN_ENABLED); + + g_signal_emit (manager, signals[MONITOR_PRIVACY_SCREEN_CHANGED], 0, + meta_monitor_get_logical_monitor (monitor), enabled); + } +} + +void +meta_monitor_manager_maybe_emit_privacy_screen_change (MetaMonitorManager *manager) +{ + MetaPrivacyScreenChangeState reason = manager->privacy_screen_change_state; + + if (reason == META_PRIVACY_SCREEN_CHANGE_STATE_NONE) + return; + + if (reason == META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_HOTKEY) + emit_privacy_screen_change (manager); + + if (reason != META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING) + { + MetaSettings *settings = meta_backend_get_settings (manager->backend); + + meta_settings_set_privacy_screen_enabled (settings, + get_global_privacy_screen_state (manager) == + META_PRIVACY_SCREEN_ENABLED); + } + + meta_dbus_display_config_emit_monitors_changed (manager->display_config); + manager->privacy_screen_change_state = META_PRIVACY_SCREEN_CHANGE_STATE_NONE; +} + static gboolean meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, GDBusMethodInvocation *invocation, diff --git a/src/backends/meta-settings-private.h b/src/backends/meta-settings-private.h index a56a8bcc4..fb9aea0dc 100644 --- a/src/backends/meta-settings-private.h +++ b/src/backends/meta-settings-private.h @@ -80,4 +80,7 @@ int meta_settings_get_xwayland_disable_extensions (MetaSettings *settings); gboolean meta_settings_is_privacy_screen_enabled (MetaSettings *settings); +void meta_settings_set_privacy_screen_enabled (MetaSettings *settings, + gboolean enabled); + #endif /* META_SETTINGS_PRIVATE_H */ diff --git a/src/backends/meta-settings.c b/src/backends/meta-settings.c index d11e0b720..f672026ea 100644 --- a/src/backends/meta-settings.c +++ b/src/backends/meta-settings.c @@ -478,6 +478,18 @@ meta_settings_is_privacy_screen_enabled (MetaSettings *settings) return settings->privacy_screen; } +void +meta_settings_set_privacy_screen_enabled (MetaSettings *settings, + gboolean enabled) +{ + if (settings->privacy_screen == enabled) + return; + + settings->privacy_screen = enabled; + g_settings_set_boolean (settings->privacy_settings, "privacy-screen", + enabled); +} + MetaSettings * meta_settings_new (MetaBackend *backend) { diff --git a/src/backends/native/meta-monitor-manager-native.c b/src/backends/native/meta-monitor-manager-native.c index 4cd02468f..7dcb9ae64 100644 --- a/src/backends/native/meta-monitor-manager-native.c +++ b/src/backends/native/meta-monitor-manager-native.c @@ -520,8 +520,23 @@ on_kms_resources_changed (MetaKms *kms, return; } - if (changes == META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN) - return; + if (changes & META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN) + { + if (manager->privacy_screen_change_state == + META_PRIVACY_SCREEN_CHANGE_STATE_NONE) + { + /* Privacy screen has been changed by "something", the best guess + * we can do is that has been triggered by an hotkey. + */ + manager->privacy_screen_change_state = + META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_HOTKEY; + } + + meta_monitor_manager_maybe_emit_privacy_screen_change (manager); + + if (changes == META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN) + return; + } handle_hotplug_event (manager); } @@ -710,7 +725,11 @@ on_kms_privacy_screen_update_result (const MetaKmsFeedback *kms_feedback, MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend)); if (meta_kms_feedback_get_result (kms_feedback) == META_KMS_FEEDBACK_FAILED) - return; + { + manager->privacy_screen_change_state = + META_PRIVACY_SCREEN_CHANGE_STATE_NONE; + return; + } on_kms_resources_changed (kms, META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN, diff --git a/src/core/display.c b/src/core/display.c index bb3918cf3..288853368 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -195,6 +195,12 @@ static void prefs_changed_callback (MetaPreference pref, static int mru_cmp (gconstpointer a, gconstpointer b); +static void +meta_display_show_osd (MetaDisplay *display, + gint monitor_idx, + const gchar *icon_name, + const gchar *message); + static void meta_display_get_property(GObject *object, guint prop_id, @@ -655,6 +661,19 @@ on_ui_scaling_factor_changed (MetaSettings *settings, meta_display_reload_cursor (display); } +static void +on_monitor_privacy_screen_changed (MetaDisplay *display, + MetaLogicalMonitor *logical_monitor, + gboolean enabled) +{ + meta_display_show_osd (display, + logical_monitor->number, + enabled ? "screen-privacy-symbolic" + : "screen-privacy-disabled-symbolic", + enabled ? _("Privacy Screen Enabled") + : _("Privacy Screen Disabled")); +} + static gboolean meta_display_init_x11_display (MetaDisplay *display, GError **error) @@ -863,6 +882,9 @@ meta_display_new (MetaContext *context, monitor_manager = meta_backend_get_monitor_manager (backend); g_signal_connect (monitor_manager, "monitors-changed-internal", G_CALLBACK (on_monitors_changed_internal), display); + g_signal_connect_object (monitor_manager, "monitor-privacy-screen-changed", + G_CALLBACK (on_monitor_privacy_screen_changed), + display, G_CONNECT_SWAPPED); display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager);