summaryrefslogtreecommitdiff
path: root/mate-panel/panel-action-button.c
diff options
context:
space:
mode:
Diffstat (limited to 'mate-panel/panel-action-button.c')
-rw-r--r--mate-panel/panel-action-button.c226
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");
}