summaryrefslogtreecommitdiff
path: root/src/ui/metacity-dialog.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2007-12-19 21:17:50 +0000
committerHavoc Pennington <hp@src.gnome.org>2007-12-19 21:17:50 +0000
commit72b08c82b16a850fd4f0cd52d58812b4180fe969 (patch)
tree587cf32237864f2ff6241c1cbf1045074eed130d /src/ui/metacity-dialog.c
parent3880951458910982807fc20ee9f11e22e947ddd2 (diff)
downloadmetacity-72b08c82b16a850fd4f0cd52d58812b4180fe969.tar.gz
metacity-72b08c82b16a850fd4f0cd52d58812b4180fe969.tar.bz2
sort source files into these directories according to which part of the WM
2007-12-19 Havoc Pennington <hp@redhat.com> * src/ui, src/core, src/include: sort source files into these directories according to which part of the WM they are supposed to be in. In an eventual plan, we should also create src/compositor/render, src/compositor/fallback and move some of the compositor stuff into that. * autogen.sh: require a newer automake, so we don't have to use a recursive build * src/ui/tabpopup.c: put in a hack to make the build temporarily work, want to commit the large rearrangement before fixing this not to include workspace.h or frame.h * src/core/iconcache.c (meta_read_icons): temporarily break this to get the build to work, want to commit the large rearrangement before fixing this file not to include theme.h svn path=/trunk/; revision=3491
Diffstat (limited to 'src/ui/metacity-dialog.c')
-rw-r--r--src/ui/metacity-dialog.c438
1 files changed, 438 insertions, 0 deletions
diff --git a/src/ui/metacity-dialog.c b/src/ui/metacity-dialog.c
new file mode 100644
index 0000000..d47a9b3
--- /dev/null
+++ b/src/ui/metacity-dialog.c
@@ -0,0 +1,438 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* Metacity dialog process */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2004 Elijah Newren
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libintl.h>
+#define _(x) dgettext (GETTEXT_PACKAGE, x)
+#define N_(x) x
+
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+static Window
+window_from_string (const char *str)
+{
+ char *end;
+ unsigned long l;
+
+ end = NULL;
+
+ l = strtoul (str, &end, 16);
+
+ if (end == NULL || end == str)
+ {
+ g_printerr (_("Could not parse \"%s\" as an integer"),
+ str);
+ return None;
+ }
+
+ if (*end != '\0')
+ {
+ g_printerr (_("Did not understand trailing characters \"%s\" in string \"%s\""),
+ end, str);
+ return None;
+ }
+
+ return l;
+}
+
+static void
+on_realize (GtkWidget *dialog,
+ void *data)
+{
+ const char *parent_str = data;
+ Window xwindow;
+
+ xwindow = window_from_string (parent_str);
+
+ gdk_error_trap_push ();
+ XSetTransientForHint (gdk_display, GDK_WINDOW_XID (dialog->window),
+ xwindow);
+ XSync (gdk_display, False);
+ gdk_error_trap_pop ();
+}
+
+static int
+kill_window_question (const char *window_name,
+ const char *parent_str,
+ guint32 timestamp)
+{
+ GtkWidget *dialog;
+ char *str, *tmp;
+
+ tmp = g_markup_escape_text (window_name, -1);
+ str = g_strdup_printf (_("\"%s\" is not responding."), tmp);
+ g_free (tmp);
+ dialog = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "<big><b>%s</b></big>\n\n<i>%s</i>",
+ str,
+ _("You may choose to wait a short while "
+ "for it to continue or force the application "
+ "to quit entirely."));
+ g_free (str);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-warning");
+
+ gtk_label_set_use_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (GTK_MESSAGE_DIALOG (dialog)->label), TRUE);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _("_Wait"),
+ GTK_RESPONSE_REJECT,
+ _("_Force Quit"),
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT);
+
+ g_signal_connect (G_OBJECT (dialog), "realize",
+ G_CALLBACK (on_realize), (char*) parent_str);
+
+ gtk_widget_realize (dialog);
+ gdk_x11_window_set_user_time (dialog->window, timestamp);
+
+ /* return our PID, then window ID that should be killed */
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ g_print ("%d\n%s\n", (int) getpid (), parent_str);
+ else
+ g_print ("%d\n0x0\n", (int) getpid ());
+
+ return 0;
+}
+
+static char*
+latin1_to_utf8 (const char *text)
+{
+ GString *str;
+ const char *p;
+
+ str = g_string_new ("");
+
+ p = text;
+ while (*p)
+ {
+ g_string_append_unichar (str, *p);
+ ++p;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+enum
+{
+ COLUMN_TITLE,
+ COLUMN_CLASS,
+ COLUMN_LAST
+};
+
+static GtkWidget*
+create_lame_apps_list (char **lame_apps)
+{
+ GtkTreeSelection *selection;
+ GtkCellRenderer *cell;
+ GtkWidget *tree_view;
+ GtkTreeViewColumn *column;
+ GtkListStore *model;
+ GtkTreeIter iter;
+ int i;
+
+ model = gtk_list_store_new (COLUMN_LAST,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+
+ g_object_unref (G_OBJECT (model));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
+
+ gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
+ GTK_SELECTION_NONE);
+
+ i = 0;
+ while (lame_apps[i])
+ {
+ char *s;
+
+ gtk_list_store_append (model, &iter);
+
+ /* window class is latin-1 */
+ s = latin1_to_utf8 (lame_apps[i+1]);
+
+ gtk_list_store_set (model,
+ &iter,
+ COLUMN_TITLE, lame_apps[i],
+ COLUMN_CLASS, s,
+ -1);
+
+ g_free (s);
+
+ i += 2;
+ }
+
+ cell = gtk_cell_renderer_text_new ();
+
+ g_object_set (G_OBJECT (cell),
+ "xpad", 2,
+ NULL);
+
+ column = gtk_tree_view_column_new_with_attributes (_("Title"),
+ cell,
+ "text", COLUMN_TITLE,
+ NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COLUMN_TITLE);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
+ GTK_TREE_VIEW_COLUMN (column));
+
+ cell = gtk_cell_renderer_text_new ();
+
+ column = gtk_tree_view_column_new_with_attributes (_("Class"),
+ cell,
+ "text", COLUMN_CLASS,
+ NULL);
+
+ gtk_tree_view_column_set_sort_column_id (column, COLUMN_CLASS);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
+ GTK_TREE_VIEW_COLUMN (column));
+
+ return tree_view;
+}
+
+static int
+warn_about_no_sm_support (char **lame_apps,
+ guint32 timestamp)
+{
+ GtkWidget *dialog;
+ GtkWidget *list;
+ GtkWidget *sw;
+ GtkWidget *button;
+
+ dialog = gtk_message_dialog_new (NULL,
+ 0,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ _("These windows do not support \"save current setup\" and will have to be restarted manually next time you log in."));
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-warning");
+
+ g_signal_connect (G_OBJECT (dialog),
+ "response",
+ G_CALLBACK (gtk_main_quit),
+ NULL);
+
+ /* Wait 4 minutes then force quit, so we don't wait around all night */
+ g_timeout_add (4 * 60 * 1000, (GSourceFunc) gtk_main_quit, NULL);
+
+ button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
+ list = create_lame_apps_list (lame_apps);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_container_set_border_width (GTK_CONTAINER (sw), 3);
+
+ gtk_container_add (GTK_CONTAINER (sw), list);
+
+ /* sw as geometry widget */
+ gtk_window_set_geometry_hints (GTK_WINDOW (dialog),
+ sw, NULL, 0);
+
+ gtk_window_set_resizable (GTK_WINDOW(dialog), TRUE);
+
+ /* applies to geometry widget; try to avoid scrollbars,
+ * but don't make the window huge
+ */
+ gtk_window_set_default_size (GTK_WINDOW (dialog),
+ 400, 225);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ sw,
+ TRUE, TRUE, 0);
+
+ gtk_window_stick (GTK_WINDOW (dialog));
+
+ gtk_widget_realize (dialog);
+ gdk_x11_window_set_user_time (dialog->window, timestamp);
+
+ gtk_widget_grab_focus (button);
+ gtk_widget_show_all (dialog);
+
+ gtk_main ();
+
+ return 0;
+}
+
+static int
+error_about_command (const char *gconf_key,
+ const char *command,
+ const char *error,
+ guint32 timestamp)
+{
+ GtkWidget *dialog;
+
+ /* FIXME offer to change the value of the command's gconf key */
+
+ if (*command != '\0')
+ dialog = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("There was an error running \"%s\":\n"
+ "%s."),
+ command, error);
+ else
+ dialog = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s", error);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "stock_dialog-error");
+
+ gtk_widget_realize (dialog);
+ gdk_x11_window_set_user_time (dialog->window, timestamp);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+
+ return 0;
+}
+
+static gchar *screen = NULL;
+static gchar *timestamp_string = NULL;
+static gboolean isset_kill_window_question = FALSE;
+static gboolean isset_warn_about_no_sm_support = FALSE;
+static gboolean isset_command_failed_error = FALSE;
+static gchar **remaining_args;
+
+static const GOptionEntry options[] = {
+ { "screen", 0, 0, G_OPTION_ARG_STRING, &screen, NULL, NULL},
+ { "timestamp", 0, 0, G_OPTION_ARG_STRING, &timestamp_string, NULL, NULL},
+ { "kill-window-question", 'k', 0, G_OPTION_ARG_NONE,
+ &isset_kill_window_question, NULL, NULL},
+ { "warn-about-no-sm-support", 'w', 0, G_OPTION_ARG_NONE,
+ &isset_warn_about_no_sm_support, NULL, NULL},
+ { "command-failed-error", 'c', 0, G_OPTION_ARG_NONE,
+ &isset_command_failed_error, NULL, NULL},
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY,
+ &remaining_args, NULL, NULL},
+ { NULL}
+};
+
+int
+main (int argc, char **argv)
+{
+ GOptionContext *ctx;
+ guint32 timestamp = 0;
+ gint num_args = 0;
+
+ bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ gtk_init (&argc, &argv);
+
+ ctx = g_option_context_new ("- Dialogs for metacity. "
+ "This program is intented for use by metacity only.");
+ g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
+ g_option_context_parse (ctx, &argc, &argv, NULL);
+ g_option_context_free (ctx);
+
+ if (timestamp_string != NULL)
+ {
+ timestamp = strtoul (timestamp_string, NULL, 10);
+ }
+
+ if (remaining_args != NULL)
+ {
+ num_args = g_strv_length (remaining_args);
+ }
+
+ if ((isset_kill_window_question && isset_warn_about_no_sm_support) ||
+ (isset_kill_window_question && isset_command_failed_error) ||
+ (isset_warn_about_no_sm_support && isset_command_failed_error) ||
+ timestamp == 0)
+ {
+ g_printerr ("bad args to metacity-dialog\n");
+ return 1;
+ }
+
+ else if (isset_kill_window_question)
+ {
+ if (num_args < 2)
+ {
+ g_printerr ("bad args to metacity-dialog\n");
+ return 1;
+ }
+ else
+ {
+ return kill_window_question (remaining_args[0],
+ remaining_args[1], timestamp);
+ }
+ }
+
+ else if (isset_warn_about_no_sm_support)
+ {
+ /* argc must be even because we want title-class pairs */
+ if (num_args == 0 || (num_args % 2) != 0)
+ {
+ g_printerr ("bad args to metacity-dialog\n");
+ return 1;
+ }
+ else
+ {
+ return warn_about_no_sm_support (&remaining_args[0], timestamp);
+ }
+ }
+
+ else if (isset_command_failed_error)
+ {
+ /* the args are the gconf key of the failed command, the text of
+ * the command, and the error message
+ */
+ if (num_args != 3)
+ {
+ g_printerr ("bad args to metacity-dialog\n");
+ return 1;
+ }
+ else
+ {
+ return error_about_command (remaining_args[0],
+ remaining_args[1], remaining_args[2], timestamp);
+ }
+ }
+ else
+ {
+ g_printerr ("bad args to metacity-dialog\n");
+ return 1;
+ }
+}