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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1952>
This commit is contained in:
Marco Trevisan (Treviño) 2021-08-02 18:22:46 +02:00 committed by Marge Bot
parent 4e10324a80
commit 8cf3485ab0
6 changed files with 135 additions and 4 deletions

View File

@ -35,6 +35,7 @@
#include "backends/meta-viewport-info.h" #include "backends/meta-viewport-info.h"
#include "core/util-private.h" #include "core/util-private.h"
#include "meta/display.h" #include "meta/display.h"
#include "meta/meta-enum-types.h"
#include "meta/meta-monitor-manager.h" #include "meta/meta-monitor-manager.h"
#define META_MONITOR_MANAGER_MIN_SCREEN_WIDTH 640 #define META_MONITOR_MANAGER_MIN_SCREEN_WIDTH 640
@ -62,6 +63,14 @@ typedef enum _MetaLogicalMonitorLayoutMode
META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2 META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL = 2
} MetaLogicalMonitorLayoutMode; } 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: * MetaCrtcAssignment:
* *
@ -149,6 +158,8 @@ struct _MetaMonitorManager
GnomePnpIds *pnp_ids; GnomePnpIds *pnp_ids;
MetaMonitorSwitchConfigType current_switch_config; 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); 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 */ #endif /* META_MONITOR_MANAGER_PRIVATE_H */

View File

@ -83,6 +83,7 @@ enum
MONITORS_CHANGED_INTERNAL, MONITORS_CHANGED_INTERNAL,
POWER_SAVE_MODE_CHANGED, POWER_SAVE_MODE_CHANGED,
CONFIRM_DISPLAY_CHANGE, CONFIRM_DISPLAY_CHANGE,
MONITOR_PRIVACY_SCREEN_CHANGED,
SIGNALS_LAST SIGNALS_LAST
}; };
@ -1092,7 +1093,11 @@ apply_privacy_screen_settings (MetaMonitorManager *manager)
meta_settings_is_privacy_screen_enabled (settings)) meta_settings_is_privacy_screen_enabled (settings))
return; return;
ensure_monitors_settings (manager); if (ensure_monitors_settings (manager))
{
manager->privacy_screen_change_state =
META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING;
}
} }
static void static void
@ -1354,6 +1359,14 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 0); 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] = obj_props[PROP_BACKEND] =
g_param_spec_object ("backend", g_param_spec_object ("backend",
"backend", "backend",
@ -1446,6 +1459,55 @@ combine_gpu_lists (MetaMonitorManager *manager,
return list; 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 static gboolean
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton, meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,

View File

@ -80,4 +80,7 @@ int meta_settings_get_xwayland_disable_extensions (MetaSettings *settings);
gboolean meta_settings_is_privacy_screen_enabled (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 */ #endif /* META_SETTINGS_PRIVATE_H */

View File

@ -478,6 +478,18 @@ meta_settings_is_privacy_screen_enabled (MetaSettings *settings)
return settings->privacy_screen; 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 * MetaSettings *
meta_settings_new (MetaBackend *backend) meta_settings_new (MetaBackend *backend)
{ {

View File

@ -520,8 +520,23 @@ on_kms_resources_changed (MetaKms *kms,
return; 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) if (changes == META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN)
return; return;
}
handle_hotplug_event (manager); 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)); MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
if (meta_kms_feedback_get_result (kms_feedback) == META_KMS_FEEDBACK_FAILED) if (meta_kms_feedback_get_result (kms_feedback) == META_KMS_FEEDBACK_FAILED)
{
manager->privacy_screen_change_state =
META_PRIVACY_SCREEN_CHANGE_STATE_NONE;
return; return;
}
on_kms_resources_changed (kms, on_kms_resources_changed (kms,
META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN, META_KMS_UPDATE_CHANGE_PRIVACY_SCREEN,

View File

@ -195,6 +195,12 @@ static void prefs_changed_callback (MetaPreference pref,
static int mru_cmp (gconstpointer a, static int mru_cmp (gconstpointer a,
gconstpointer b); gconstpointer b);
static void
meta_display_show_osd (MetaDisplay *display,
gint monitor_idx,
const gchar *icon_name,
const gchar *message);
static void static void
meta_display_get_property(GObject *object, meta_display_get_property(GObject *object,
guint prop_id, guint prop_id,
@ -655,6 +661,19 @@ on_ui_scaling_factor_changed (MetaSettings *settings,
meta_display_reload_cursor (display); 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 static gboolean
meta_display_init_x11_display (MetaDisplay *display, meta_display_init_x11_display (MetaDisplay *display,
GError **error) GError **error)
@ -863,6 +882,9 @@ meta_display_new (MetaContext *context,
monitor_manager = meta_backend_get_monitor_manager (backend); monitor_manager = meta_backend_get_monitor_manager (backend);
g_signal_connect (monitor_manager, "monitors-changed-internal", g_signal_connect (monitor_manager, "monitors-changed-internal",
G_CALLBACK (on_monitors_changed_internal), display); 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); display->pad_action_mapper = meta_pad_action_mapper_new (monitor_manager);