[mutter] core: Implement MetaCloseDialogDefault



commit 020e0bb2acf89f9b229e89a305a88617babecadd
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jul 11 13:12:13 2016 +0200

    core: Implement MetaCloseDialogDefault
    
    This is basically a copy of the implementation currently residing
    in src/core/delete.c, which will be eventually deleted in favor
    of this one.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711619

 po/POTFILES.in                               |    1 +
 src/Makefile.am                              |    2 +
 src/core/meta-close-dialog-default-private.h |   33 +++
 src/core/meta-close-dialog-default.c         |  279 ++++++++++++++++++++++++++
 4 files changed, 315 insertions(+), 0 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a463e64..416c071 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -17,6 +17,7 @@ src/core/display.c
 src/core/errors.c
 src/core/keybindings.c
 src/core/main.c
+src/core/meta-close-dialog-default.c
 src/core/mutter.c
 src/core/prefs.c
 src/core/screen.c
diff --git a/src/Makefile.am b/src/Makefile.am
index ac5786a..2e8d73b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -224,6 +224,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =      \
        core/core.c                             \
        core/meta-close-dialog.c                \
        meta/meta-close-dialog.h                \
+       core/meta-close-dialog-default.c        \
+       core/meta-close-dialog-default-private.h        \
        core/delete.c                           \
        core/display.c                          \
        core/display-private.h                  \
diff --git a/src/core/meta-close-dialog-default-private.h b/src/core/meta-close-dialog-default-private.h
new file mode 100644
index 0000000..fb4d1d6
--- /dev/null
+++ b/src/core/meta-close-dialog-default-private.h
@@ -0,0 +1,33 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2016 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef META_CLOSE_DIALOG_DEFAULT_H
+#define META_CLOSE_DIALOG_DEFAULT_H
+
+#define META_TYPE_CLOSE_DIALOG_DEFAULT (meta_close_dialog_default_get_type ())
+G_DECLARE_FINAL_TYPE (MetaCloseDialogDefault,
+                      meta_close_dialog_default,
+                      META, CLOSE_DIALOG_DEFAULT,
+                      GObject)
+
+MetaCloseDialog * meta_close_dialog_default_new (MetaWindow *window);
+
+#endif /* META_CLOSE_DIALOG_DEFAULT_H */
diff --git a/src/core/meta-close-dialog-default.c b/src/core/meta-close-dialog-default.c
new file mode 100644
index 0000000..55eb897
--- /dev/null
+++ b/src/core/meta-close-dialog-default.c
@@ -0,0 +1,279 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2001, 2002 Havoc Pennington
+ * Copyright (C) 2004 Elijah Newren
+ * Copyright (C) 2016 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#define _XOPEN_SOURCE /* for kill() */
+
+#include <config.h>
+#include "util-private.h"
+#include "window-private.h"
+#include <meta/meta-close-dialog.h>
+#include "meta-close-dialog-default-private.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+typedef struct _MetaCloseDialogDefaultPrivate MetaCloseDialogDefaultPrivate;
+
+struct _MetaCloseDialogDefault
+{
+  GObject parent_instance;
+  MetaWindow *window;
+  int dialog_pid;
+  guint child_watch_id;
+};
+
+enum {
+  PROP_0,
+  PROP_WINDOW,
+  N_PROPS
+};
+
+GParamSpec *pspecs[N_PROPS] = { NULL };
+
+static void meta_close_dialog_iface_init (MetaCloseDialogInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaCloseDialogDefault, meta_close_dialog_default,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (META_TYPE_CLOSE_DIALOG,
+                                                meta_close_dialog_iface_init))
+
+static void
+dialog_exited (GPid     pid,
+               int      status,
+               gpointer user_data)
+{
+  MetaCloseDialogDefault *dialog = user_data;
+
+  dialog->dialog_pid = -1;
+
+  /* exit status of 0 means the user pressed "Force Quit" */
+  if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
+    g_signal_emit_by_name (dialog, "response", META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE);
+}
+
+static void
+present_existing_delete_dialog (MetaCloseDialogDefault *dialog)
+{
+  MetaWindow *window;
+  GSList *windows;
+  GSList *tmp;
+
+  window = dialog->window;
+
+  if (dialog->dialog_pid < 0)
+    return;
+
+  meta_topic (META_DEBUG_PING,
+              "Presenting existing ping dialog for %s\n",
+              window->desc);
+
+  /* Activate transient for window that belongs to
+   * mutter-dialog
+   */
+  windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
+  tmp = windows;
+
+  while (tmp != NULL)
+    {
+      MetaWindow *w = tmp->data;
+
+      if (w->transient_for == window && w->res_class &&
+          g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
+        {
+          meta_window_activate (w, CLUTTER_CURRENT_TIME);
+          break;
+        }
+
+      tmp = tmp->next;
+    }
+
+  g_slist_free (windows);
+}
+
+static void
+meta_close_dialog_default_show (MetaCloseDialog *dialog)
+{
+  MetaCloseDialogDefault *dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog);
+  MetaWindow *window = dialog_default->window;
+  gchar *window_title, *window_content, *tmp;
+  GPid dialog_pid;
+
+  if (dialog_default->dialog_pid >= 0)
+    {
+      present_existing_delete_dialog (dialog_default);
+      return;
+    }
+
+  /* This is to get a better string if the title isn't representable
+   * in the locale encoding; actual conversion to UTF-8 is done inside
+   * meta_show_dialog */
+  if (window->title && window->title[0])
+    {
+      tmp = g_locale_from_utf8 (window->title, -1, NULL, NULL, NULL);
+      if (tmp == NULL)
+        window_title = NULL;
+      else
+        window_title = window->title;
+      g_free (tmp);
+    }
+  else
+    {
+      window_title = NULL;
+    }
+
+  if (window_title)
+    /* Translators: %s is a window title */
+    tmp = g_strdup_printf (_("ā€œ%sā€ is not responding."), window_title);
+  else
+    tmp = g_strdup (_("Application is not responding."));
+
+  window_content = g_strdup_printf (
+      "<big><b>%s</b></big>\n\n%s",
+      tmp,
+      _("You may choose to wait a short while for it to "
+        "continue or force the application to quit entirely."));
+
+  dialog_pid =
+    meta_show_dialog ("--question",
+                      window_content, NULL,
+                      window->screen->screen_name,
+                      _("_Force Quit"), _("_Wait"),
+                      "face-sad-symbolic", window->xwindow,
+                      NULL, NULL);
+
+  g_free (window_content);
+  g_free (tmp);
+
+  dialog_default->dialog_pid = dialog_pid;
+  g_child_watch_add (dialog_pid, dialog_exited, dialog);
+}
+
+static void
+meta_close_dialog_default_hide (MetaCloseDialog *dialog)
+{
+  MetaCloseDialogDefault *dialog_default;
+
+  dialog_default = META_CLOSE_DIALOG_DEFAULT (dialog);
+
+  if (dialog_default->child_watch_id)
+    {
+      g_source_remove (dialog_default->child_watch_id);
+      dialog_default->child_watch_id = 0;
+    }
+
+  if (dialog_default->dialog_pid > -1)
+    kill (dialog_default->dialog_pid, SIGTERM);
+}
+
+static void
+meta_close_dialog_iface_init (MetaCloseDialogInterface *iface)
+{
+  iface->show = meta_close_dialog_default_show;
+  iface->hide = meta_close_dialog_default_hide;
+}
+
+static void
+meta_close_dialog_default_finalize (GObject *object)
+{
+  MetaCloseDialogDefault *dialog;
+
+  dialog = META_CLOSE_DIALOG_DEFAULT (object);
+
+  if (dialog->child_watch_id)
+    g_source_remove (dialog->child_watch_id);
+
+  if (dialog->dialog_pid > -1)
+    {
+      kill (dialog->dialog_pid, SIGKILL);
+      dialog->dialog_pid = -1;
+    }
+
+  G_OBJECT_CLASS (meta_close_dialog_default_parent_class)->finalize (object);
+}
+
+static void
+meta_close_dialog_default_set_property (GObject      *object,
+                                        guint         prop_id,
+                                        const GValue *value,
+                                        GParamSpec   *pspec)
+{
+  MetaCloseDialogDefault *dialog;
+
+  dialog = META_CLOSE_DIALOG_DEFAULT (object);
+
+  switch (prop_id)
+    {
+    case PROP_WINDOW:
+      dialog->window = g_value_get_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+meta_close_dialog_default_get_property (GObject    *object,
+                                        guint       prop_id,
+                                        GValue     *value,
+                                        GParamSpec *pspec)
+{
+  MetaCloseDialogDefault *dialog;
+
+  dialog = META_CLOSE_DIALOG_DEFAULT (object);
+
+  switch (prop_id)
+    {
+    case PROP_WINDOW:
+      g_value_set_object (value, dialog->window);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+meta_close_dialog_default_class_init (MetaCloseDialogDefaultClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = meta_close_dialog_default_finalize;
+  object_class->set_property = meta_close_dialog_default_set_property;
+  object_class->get_property = meta_close_dialog_default_get_property;
+
+  g_object_class_override_property (object_class, PROP_WINDOW, "window");
+}
+
+static void
+meta_close_dialog_default_init (MetaCloseDialogDefault *dialog)
+{
+  dialog->dialog_pid = -1;
+}
+
+MetaCloseDialog *
+meta_close_dialog_default_new (MetaWindow *window)
+{
+  return g_object_new (META_TYPE_CLOSE_DIALOG_DEFAULT,
+                       "window", window,
+                       NULL);
+}


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