[mutter/wip/display-no-wayland: 30/33] MetaPlugin: add a UI hook for confirming display changes



commit 40b6837e9da5af977cda851e9245abe37433f205
Author: Giovanni Campagna <gcampagn redhat com>
Date:   Mon Jul 29 10:12:24 2013 +0200

    MetaPlugin: add a UI hook for confirming display changes
    
    We want to show a dialog when a display change happens from the
    control center. To do so, add a new vfunc to MetaPlugin and
    call it when a configuration change is requested via DBus.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=705670

 src/compositor/meta-plugin-manager.c |   24 ++++++++++++++++++
 src/compositor/meta-plugin-manager.h |    2 +
 src/compositor/meta-plugin.c         |   11 ++++++++
 src/compositor/plugins/default.c     |   33 +++++++++++++++++++++++++
 src/core/monitor-private.h           |    3 ++
 src/core/monitor.c                   |   44 ++++++++++++++++++++++++++++++----
 src/core/util.c                      |    9 +++++-
 src/meta/meta-plugin.h               |   20 +++++++++++++++
 8 files changed, 139 insertions(+), 7 deletions(-)
---
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
index 130a82b..43f9931 100644
--- a/src/compositor/meta-plugin-manager.c
+++ b/src/compositor/meta-plugin-manager.c
@@ -85,12 +85,20 @@ meta_plugin_manager_load (const gchar       *plugin_name)
   g_free (path);
 }
 
+static void
+on_confirm_display_change (MetaMonitorManager *monitors,
+                           MetaPluginManager  *plugin_mgr)
+{
+  meta_plugin_manager_confirm_display_change (plugin_mgr);
+}
+
 MetaPluginManager *
 meta_plugin_manager_new (MetaScreen *screen)
 {
   MetaPluginManager *plugin_mgr;
   MetaPluginClass *klass;
   MetaPlugin *plugin;
+  MetaMonitorManager *monitors;
 
   plugin_mgr = g_new0 (MetaPluginManager, 1);
   plugin_mgr->screen = screen;
@@ -101,6 +109,10 @@ meta_plugin_manager_new (MetaScreen *screen)
   if (klass->start)
     klass->start (plugin);
 
+  monitors = meta_monitor_manager_get ();
+  g_signal_connect (monitors, "confirm-display-change",
+                    G_CALLBACK (on_confirm_display_change), plugin_mgr);
+
   return plugin_mgr;
 }
 
@@ -320,3 +332,15 @@ meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
   else
     return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
 }
+
+void
+meta_plugin_manager_confirm_display_change (MetaPluginManager *plugin_mgr)
+{
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
+
+  if (klass->confirm_display_change)
+    return klass->confirm_display_change (plugin);
+  else
+    return meta_plugin_complete_display_change (plugin, TRUE);
+}
diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h
index 9df24c1..215d450 100644
--- a/src/compositor/meta-plugin-manager.h
+++ b/src/compositor/meta-plugin-manager.h
@@ -73,4 +73,6 @@ gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager  *mgr,
 gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
                                             XEvent            *xev);
 
+void     meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr);
+
 #endif
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
index a7ee113..daf5824 100644
--- a/src/compositor/meta-plugin.c
+++ b/src/compositor/meta-plugin.c
@@ -41,6 +41,7 @@
 
 #include "compositor-private.h"
 #include "meta-window-actor-private.h"
+#include "monitor-private.h"
 
 G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
 
@@ -338,3 +339,13 @@ meta_plugin_get_screen (MetaPlugin *plugin)
 
   return priv->screen;
 }
+
+void
+meta_plugin_complete_display_change (MetaPlugin *plugin,
+                                     gboolean    ok)
+{
+  MetaMonitorManager *manager;
+
+  manager = meta_monitor_manager_get ();
+  meta_monitor_manager_confirm_configuration (manager, ok);
+}
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
index b125e3a..6177f01 100644
--- a/src/compositor/plugins/default.c
+++ b/src/compositor/plugins/default.c
@@ -101,6 +101,8 @@ static void kill_window_effects   (MetaPlugin      *plugin,
                                    MetaWindowActor *actor);
 static void kill_switch_workspace (MetaPlugin      *plugin);
 
+static void confirm_display_change (MetaPlugin *plugin);
+
 static const MetaPluginInfo * plugin_info (MetaPlugin *plugin);
 
 META_PLUGIN_DECLARE(MetaDefaultPlugin, meta_default_plugin);
@@ -208,6 +210,7 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
   plugin_class->plugin_info      = plugin_info;
   plugin_class->kill_window_effects   = kill_window_effects;
   plugin_class->kill_switch_workspace = kill_switch_workspace;
+  plugin_class->confirm_display_change = confirm_display_change;
 
   g_type_class_add_private (gobject_class, sizeof (MetaDefaultPluginPrivate));
 }
@@ -836,3 +839,33 @@ plugin_info (MetaPlugin *plugin)
 
   return &priv->info;
 }
+
+static void
+on_dialog_closed (GPid     pid,
+                  gint     status,
+                  gpointer user_data)
+{
+  MetaPlugin *plugin = user_data;
+  gboolean ok;
+
+  ok = g_spawn_check_exit_status (status, NULL);
+  meta_plugin_complete_display_change (plugin, ok);
+}
+
+static void
+confirm_display_change (MetaPlugin *plugin)
+{
+  GPid pid;
+
+  pid = meta_show_dialog ("--question",
+                          "Does the display look OK?",
+                          "20",
+                          NULL,
+                          "_Keep This Configuration",
+                          "_Restore Previous Configuration",
+                          "preferences-desktop-display",
+                          0,
+                          NULL, NULL);
+
+  g_child_watch_add (pid, on_dialog_closed, plugin);
+}
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index 03530c9..e25868c 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -243,6 +243,9 @@ void                meta_monitor_manager_apply_configuration (MetaMonitorManager
                                                               MetaOutputInfo     **outputs,
                                                               unsigned int         n_outputs);
 
+void                meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
+                                                                gboolean            ok);
+
 #define META_TYPE_MONITOR_CONFIG            (meta_monitor_config_get_type ())
 #define META_MONITOR_CONFIG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, 
MetaMonitorConfig))
 #define META_MONITOR_CONFIG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_MONITOR_CONFIG, 
MetaMonitorConfigClass))
diff --git a/src/core/monitor.c b/src/core/monitor.c
index c0ebe78..912c02f 100644
--- a/src/core/monitor.c
+++ b/src/core/monitor.c
@@ -114,6 +114,7 @@ struct _MetaMonitorManagerClass
 
 enum {
   MONITORS_CHANGED,
+  CONFIRM_DISPLAY_CHANGE,
   SIGNALS_LAST
 };
 
@@ -1094,6 +1095,14 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
                   NULL, NULL, NULL,
                  G_TYPE_NONE, 0);
 
+  signals[CONFIRM_DISPLAY_CHANGE] =
+    g_signal_new ("confirm-display-change",
+                 G_TYPE_FROM_CLASS (object_class),
+                 G_SIGNAL_RUN_LAST,
+                 0,
+                  NULL, NULL, NULL,
+                 G_TYPE_NONE, 0);
+
   g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
 }
 
@@ -1549,8 +1558,9 @@ save_config_timeout (gpointer user_data)
 {
   MetaMonitorManager *manager = user_data;
 
-  meta_monitor_config_make_persistent (manager->config);
+  meta_monitor_config_restore_previous (manager->config, manager);
 
+  manager->persistent_timeout_id = 0;
   return G_SOURCE_REMOVE;
 }
 
@@ -1739,7 +1749,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 
   /* If we were in progress of making a persistent change and we see a
      new request, it's likely that the old one failed in some way, so
-     don't save it.
+     don't save it, but also don't queue for restoring it.
   */ 
   if (manager->persistent_timeout_id && persistent)
     {
@@ -1757,17 +1767,41 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
   g_ptr_array_unref (output_infos);
 
   /* Update MetaMonitorConfig data structures immediately so that we
-     don't revert the change at the next XRandR event, then wait 20
-     seconds and save the change to disk
+     don't revert the change at the next XRandR event, then ask the plugin
+     manager (through MetaScreen) to confirm the display change with the
+     appropriate UI. Then wait 20 seconds and if not confirmed, revert the
+     configuration.
   */
   meta_monitor_config_update_current (manager->config, manager);
   if (persistent)
-    manager->persistent_timeout_id = g_timeout_add_seconds (20, save_config_timeout, manager);
+    {
+      manager->persistent_timeout_id = g_timeout_add_seconds (20, save_config_timeout, manager);
+      g_signal_emit (manager, signals[CONFIRM_DISPLAY_CHANGE], 0);
+    }
 
   meta_dbus_display_config_complete_apply_configuration (skeleton, invocation);
   return TRUE;
 }
 
+void
+meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
+                                            gboolean            ok)
+{
+  if (!manager->persistent_timeout_id)
+    {
+      /* too late */
+      return;
+    }
+
+  g_source_remove (manager->persistent_timeout_id);
+  manager->persistent_timeout_id = 0;
+
+  if (ok)
+    meta_monitor_config_make_persistent (manager->config);
+  else
+    meta_monitor_config_restore_previous (manager->config, manager);
+}
+
 #ifdef HAVE_RANDR
 static void
 handle_change_backlight_xrandr (MetaMonitorManager *manager,
diff --git a/src/core/util.c b/src/core/util.c
index e36353f..c3af1a7 100644
--- a/src/core/util.c
+++ b/src/core/util.c
@@ -639,8 +639,13 @@ meta_show_dialog (const char *type,
 
   append_argument (args, "zenity");
   append_argument (args, type);
-  append_argument (args, "--display");
-  append_argument (args, display);
+
+  if (display)
+    {
+      append_argument (args, "--display");
+      append_argument (args, display);
+    }
+
   append_argument (args, "--class");
   append_argument (args, "mutter-dialog");
   append_argument (args, "--title");
diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h
index 3ea3435..d2643c2 100644
--- a/src/meta/meta-plugin.h
+++ b/src/meta/meta-plugin.h
@@ -206,6 +206,21 @@ struct _MetaPluginClass
                                  MetaKeyBinding *binding);
 
   /**
+   * MetaPluginClass::confirm_display_config:
+   * @plugin: a #MetaPlugin
+   *
+   * Virtual function called when the display configuration changes.
+   * The common way to implement this function is to show some form
+   * of modal dialog that should ask the user if everything was ok.
+   *
+   * When confirmed by the user, the plugin must call meta_plugin_complete_display_change()
+   * to make the configuration permanent. If that function is not
+   * called within the timeout, the previous configuration will be
+   * reapplied.
+   */
+  void (*confirm_display_change) (MetaPlugin *plugin);
+
+  /**
    * MetaPluginClass::plugin_info:
    * @plugin: a #MetaPlugin
    *
@@ -214,6 +229,7 @@ struct _MetaPluginClass
    * Returns: a #MetaPluginInfo.
    */
   const MetaPluginInfo * (*plugin_info) (MetaPlugin *plugin);
+
 };
 
 /**
@@ -360,6 +376,10 @@ void
 meta_plugin_destroy_completed (MetaPlugin      *plugin,
                                MetaWindowActor *actor);
 
+void
+meta_plugin_complete_display_change (MetaPlugin *plugin,
+                                     gboolean    ok);
+
 /**
  * MetaModalOptions:
  * @META_MODAL_POINTER_ALREADY_GRABBED: if set the pointer is already


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]