summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backends/meta-monitor-manager-private.h13
-rw-r--r--src/backends/meta-monitor-manager.c64
-rw-r--r--src/backends/meta-settings-private.h3
-rw-r--r--src/backends/meta-settings.c12
-rw-r--r--src/backends/native/meta-monitor-manager-native.c25
-rw-r--r--src/core/display.c22
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
@@ -196,6 +196,12 @@ 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,
GValue *value,
@@ -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);