diff options
Diffstat (limited to 'mate-panel/panel-action-button.c')
-rw-r--r-- | mate-panel/panel-action-button.c | 226 |
1 files changed, 207 insertions, 19 deletions
diff --git a/mate-panel/panel-action-button.c b/mate-panel/panel-action-button.c index 2c4569c1..6fad288f 100644 --- a/mate-panel/panel-action-button.c +++ b/mate-panel/panel-action-button.c @@ -4,6 +4,7 @@ * * Copyright (C) 2002 Sun Microsystems, Inc. * Copyright (C) 2004 Red Hat, Inc. + * Copyright (C) 2012-2021 MATE Developers * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -60,6 +61,11 @@ #include "panel-force-quit.h" #endif +#ifdef HAVE_WAYLAND +#include <gdk/gdkwayland.h> + +#endif + enum { PROP_0, PROP_ACTION_TYPE, @@ -212,13 +218,202 @@ panel_action_logout (GtkWidget *widget) PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL); } +/* Shutdown + */ +#ifdef HAVE_WAYLAND static void -panel_action_shutdown (GtkWidget *widget) +show_error_dialog (GtkWidget *label) { - PanelSessionManager *manager; + GtkWidget *dialog, *box, *content_area, *button, *image; + dialog = gtk_dialog_new (); + button = gtk_dialog_add_button (GTK_DIALOG(dialog), + "Cancel", + GTK_RESPONSE_CANCEL); + + image = gtk_image_new_from_icon_name ("process-stop", GTK_ICON_SIZE_MENU); + gtk_button_set_image (GTK_BUTTON (button), image); + + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 6); + gtk_container_set_border_width (GTK_CONTAINER (box), 16); + gtk_container_add (GTK_CONTAINER (content_area), box); + g_signal_connect_swapped (dialog, "response", + G_CALLBACK (gtk_widget_destroy), + dialog); + + gtk_widget_show_all (dialog); +} +static void wayland_shutdown_response_cb (GtkWidget *dialog, gint response_id) + { + int ret; - manager = panel_session_manager_get (); - panel_session_manager_request_shutdown (manager); + if (response_id == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy (dialog); + return; + } + + if (response_id == GTK_RESPONSE_OK) + { + gtk_widget_destroy (dialog); + system ("shutdown now"); + /*Try the system shutdown command first. + *This will fail if root is logged in + *Note that if -f --force was used this would block proper unmounting + *if this fails try systemd in case it's installed as it commonly is + *FIXME: we also need a logind equivalent for non-systemd users + *with session managers running as root + */ + system ("systemctl poweroff -i"); + return; + } + + if (response_id == GTK_RESPONSE_ACCEPT) + { + gtk_widget_destroy (dialog); + system ("reboot now"); + /*Same approach as shutdown command + *FIXME: we also need a logind equivalent for non-systemd users + *with session managers running as root + */ + system ("systemctl reboot -i"); + return; + } + + if (response_id == GTK_RESPONSE_REJECT) + { + gtk_widget_destroy (dialog); + /*FIXME: we also need a logind equivalent for non-systemd users + *with session managers running as root + */ + ret = system ("systemctl hibernate -i"); + if (ret != 0) + { + GtkWidget *label; + label = gtk_label_new ("Hibernation not supported on this system" "\n" "\n" + "The \"resume = \" boot command line option must be set to a swap partition or file" "\n" + "Swapfile or partition must be large enough to support hibernation" "\n" + "System and hardware must support hibernation"); + show_error_dialog (label); + } + return; + } + + if (response_id == GTK_RESPONSE_APPLY) + { + gtk_widget_destroy (dialog); + /*FIXME: we also need a logind equivalent for non-systemd users + *with session managers running as root + */ + ret = system ("systemctl suspend -i"); + if (ret != 0) + { + GtkWidget *label; + label = gtk_label_new ("Suspend not supported on this system" "\n" "\n" + "Hardware and Firmware must support sleep / suspend"); + show_error_dialog (label); + } + + return; + } + } + +static GtkWidget* +wayland_shutdown_dialog_add_button (GtkDialog *dialog, + const gchar *button_text, + const gchar *icon_name, + gint response_id) +{ + GtkWidget *button; + + button = gtk_button_new_with_mnemonic (button_text); + gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON)); + + gtk_button_set_use_underline (GTK_BUTTON (button), TRUE); + gtk_style_context_add_class (gtk_widget_get_style_context (button), "text-button"); + gtk_widget_set_can_default (button, TRUE); + gtk_widget_show (button); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id); + + return button; +} +#endif +static void +panel_action_shutdown (GtkWidget *widget) +{ +#ifdef HAVE_WAYLAND + GdkDisplay *display = gdk_screen_get_display (gdk_screen_get_default ()); + if (GDK_IS_WAYLAND_DISPLAY (display)) + { + GtkWidget *dialog, *hbox, *buttonbox, *shutdown_btn, *label; + GtkStyleContext *context; + + dialog = gtk_dialog_new_with_buttons ("System Shutdown", + NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + NULL, + NULL, + NULL); + + /*Window icons in dialogs are currently broken or unsupported + *in many wayland compositors but this may not always be so + */ + gtk_window_set_icon_name (GTK_WINDOW (dialog), "system-shutdown"); + context = gtk_widget_get_style_context (GTK_WIDGET (dialog)); + gtk_style_context_add_class (context, "logout-dialog"); + context = NULL; + + /*We use the inbuilt gtk response types for simplicity*/ + wayland_shutdown_dialog_add_button (GTK_DIALOG (dialog), + _("S_uspend"), "battery", + GTK_RESPONSE_APPLY); + + wayland_shutdown_dialog_add_button (GTK_DIALOG (dialog), + _("_Hibernate"), "drive-harddisk", + GTK_RESPONSE_REJECT); + + wayland_shutdown_dialog_add_button (GTK_DIALOG (dialog), + _("_Restart"), "view-refresh", + GTK_RESPONSE_ACCEPT); + + wayland_shutdown_dialog_add_button (GTK_DIALOG (dialog), + _("_Cancel"), "process-stop", + GTK_RESPONSE_CANCEL); + + shutdown_btn = wayland_shutdown_dialog_add_button (GTK_DIALOG (dialog), + _("_Shut Down"), "system-shutdown", + GTK_RESPONSE_OK); + + g_signal_connect_swapped (dialog, "response", + G_CALLBACK (wayland_shutdown_response_cb), + dialog); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + + label = gtk_label_new ("Shut this system down now?"); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 6); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 16); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + hbox); + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + buttonbox = gtk_widget_get_parent (shutdown_btn); + gtk_widget_set_halign (buttonbox,GTK_ALIGN_CENTER); + context = gtk_widget_get_style_context (buttonbox); + gtk_style_context_add_class (context, "linked"); + context = NULL; + gtk_widget_show_all (dialog); + } + else +#endif + { + PanelSessionManager *manager; + manager = panel_session_manager_get (); + panel_session_manager_request_shutdown (manager); + } } static gboolean @@ -228,7 +423,11 @@ panel_action_shutdown_reboot_is_disabled (void) if (panel_lockdown_get_disable_log_out()) return TRUE; - +#ifdef HAVE_WAYLAND + GdkDisplay *display = gdk_screen_get_display (gdk_screen_get_default()); + if (!(panel_lockdown_get_disable_log_out()) && (GDK_IS_WAYLAND_DISPLAY (display))) + return FALSE; +#endif manager = panel_session_manager_get (); return (!panel_session_manager_is_shutdown_available (manager)); @@ -272,7 +471,7 @@ panel_action_force_quit (GtkWidget *widget) } #endif flags = GTK_DIALOG_DESTROY_WITH_PARENT; - dialog = gtk_message_dialog_new (GTK_WINDOW (widget), + dialog = gtk_message_dialog_new (NULL, flags, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, @@ -314,7 +513,6 @@ panel_action_connect_server (GtkWidget *widget) } typedef struct { - PanelActionButtonType type; char *icon_name; char *text; char *tooltip; @@ -331,12 +529,10 @@ typedef struct { */ static PanelAction actions [PANEL_ACTION_LAST] = { [PANEL_ACTION_NONE] = { - PANEL_ACTION_NONE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, [PANEL_ACTION_LOCK] = { - PANEL_ACTION_LOCK, PANEL_ICON_LOCKSCREEN, N_("Lock Screen"), N_("Protect your computer from unauthorized use"), @@ -348,7 +544,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_action_lock_is_disabled }, [PANEL_ACTION_LOGOUT] = { - PANEL_ACTION_LOGOUT, PANEL_ICON_LOGOUT, /* when changing one of those two strings, don't forget to * update the ones in panel-menu-items.c (look for @@ -361,7 +556,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_lockdown_get_disable_log_out }, [PANEL_ACTION_RUN] = { - PANEL_ACTION_RUN, PANEL_ICON_RUN, N_("Run Application..."), N_("Run an application by typing a command or choosing from a list"), @@ -371,7 +565,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_lockdown_get_disable_command_line }, [PANEL_ACTION_SEARCH] = { - PANEL_ACTION_SEARCH, PANEL_ICON_SEARCHTOOL, N_("Search for Files..."), N_("Locate documents and folders on this computer by name or content"), @@ -380,7 +573,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_action_search, NULL, NULL, NULL }, [PANEL_ACTION_FORCE_QUIT] = { - PANEL_ACTION_FORCE_QUIT, PANEL_ICON_FORCE_QUIT, N_("Force Quit"), N_("Force a misbehaving application to quit"), @@ -390,7 +582,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_lockdown_get_disable_force_quit }, [PANEL_ACTION_CONNECT_SERVER] = { - PANEL_ACTION_CONNECT_SERVER, PANEL_ICON_REMOTE, /* FIXME icon */ N_("Connect to Server..."), N_("Connect to a remote computer or shared disk"), @@ -399,7 +590,6 @@ static PanelAction actions [PANEL_ACTION_LAST] = { panel_action_connect_server, NULL, NULL, NULL }, [PANEL_ACTION_SHUTDOWN] = { - PANEL_ACTION_SHUTDOWN, PANEL_ICON_SHUTDOWN, N_("Shut Down..."), N_("Shut down the computer"), @@ -476,8 +666,7 @@ panel_action_button_finalize (GObject *object) g_signal_handlers_disconnect_by_func (button->priv->settings, G_CALLBACK (panel_action_button_type_changed), button); - g_object_unref (button->priv->settings); - button->priv->settings = NULL; + g_clear_object (&button->priv->settings); } button->priv->info = NULL; @@ -715,7 +904,6 @@ panel_action_button_load (PanelActionButtonType type, button = g_object_new (PANEL_TYPE_ACTION_BUTTON, "action-type", type, NULL); - button->priv->info = mate_panel_applet_register (GTK_WIDGET (button), NULL, NULL, panel, locked, position, @@ -889,7 +1077,7 @@ panel_action_button_set_dnd_enabled (PanelActionButton *button, } else gtk_drag_source_unset (GTK_WIDGET (button)); - button->priv->dnd_enabled = enabled; + button->priv->dnd_enabled = (enabled != FALSE); g_object_notify (G_OBJECT (button), "dnd-enabled"); } |