lightdm-gtk-greeter-team team mailing list archive
-
lightdm-gtk-greeter-team team
-
Mailing list archive
-
Message #00673
[Merge] lp:~kalgasnik/lightdm-gtk-greeter/screenshot into lp:lightdm-gtk-greeter
Andrew P. has proposed merging lp:~kalgasnik/lightdm-gtk-greeter/screenshot into lp:lightdm-gtk-greeter.
Requested reviews:
LightDM Gtk+ Greeter Development Team (lightdm-gtk-greeter-team)
For more details, see:
https://code.launchpad.net/~kalgasnik/lightdm-gtk-greeter/screenshot/+merge/243143
1. Keyboard accelerators: controlled by greeter without passing them to GtkWindow
Some old code removed, logic of map/unmap changed.
2. PrintScreen: taking screenshot.
Option: max-screenshots-count = [integer_value]
value > 0: save only last [value] screenshots and remove old files
-1: allow any count of files in screenshots directory
0: disable PrintScreen key
Default value: 10.
Path to save files: /var/log/lightdm-gtk-greeter-screenshots or %TMP/lightdm-gtk-greeter-screenshots (if %TMP defined).
--
Your team LightDM Gtk+ Greeter Development Team is requested to review the proposed merge of lp:~kalgasnik/lightdm-gtk-greeter/screenshot into lp:lightdm-gtk-greeter.
=== modified file 'src/greeterbackground.c'
--- src/greeterbackground.c 2014-08-31 17:45:52 +0000
+++ src/greeterbackground.c 2014-11-28 11:56:32 +0000
@@ -108,8 +108,6 @@
/* Widget to display on active monitor */
GtkWidget* child;
- /* List of groups <GtkAccelGroup*> for greeter screens windows */
- GSList* accel_groups;
/* Mapping monitor name <gchar*> to its config <MonitorConfig*> */
GHashTable* configs;
@@ -284,7 +282,6 @@
self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, GREETER_BACKGROUND_TYPE, GreeterBackgroundPrivate);
self->priv->screen = NULL;
self->priv->screen_monitors_changed_handler_id = 0;
- self->priv->accel_groups = NULL;
self->priv->configs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)monitor_config_free);
self->priv->default_config = monitor_config_copy(&DEFAULT_MONITOR_CONFIG, NULL);
@@ -302,7 +299,7 @@
self->priv->laptop_lid_closed = FALSE;
}
-GreeterBackground*
+GreeterBackground*
greeter_background_new(GtkWidget* child)
{
GreeterBackground* background = GREETER_BACKGROUND(g_object_new(greeter_background_get_type(), NULL));
@@ -489,9 +486,6 @@
monitor->window_draw_handler_id = g_signal_connect(G_OBJECT(monitor->window), "draw",
G_CALLBACK(monitor_window_draw_cb),
monitor);
- GSList* item;
- for(item = priv->accel_groups; item != NULL; item = g_slist_next(item))
- gtk_window_add_accel_group(monitor->window, item->data);
if(priv->follow_cursor)
g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event",
@@ -859,25 +853,6 @@
return priv->active_monitor ? &priv->active_monitor->geometry : NULL;
}
-void
-greeter_background_add_accel_group(GreeterBackground* background,
- GtkAccelGroup* group)
-{
- g_return_if_fail(GREETER_IS_BACKGROUND(background));
- g_return_if_fail(group != NULL);
- GreeterBackgroundPrivate* priv = background->priv;
-
- if(priv->monitors)
- {
- gint i;
- for(i = 0; i < priv->monitors_size; ++i)
- if(priv->monitors[i].window)
- gtk_window_add_accel_group(priv->monitors[i].window, group);
- }
-
- priv->accel_groups = g_slist_append(priv->accel_groups, group);
-}
-
static gboolean
background_config_initialize(BackgroundConfig* config,
const gchar* value)
@@ -904,7 +879,7 @@
config->options.image.mode = SCALING_MODE_ZOOMED;
config->options.image.path = g_strdup(value);
- config->type = BACKGROUND_TYPE_IMAGE;
+ config->type = BACKGROUND_TYPE_IMAGE;
}
return TRUE;
}
@@ -1165,7 +1140,7 @@
Display* display,
Pixmap xpixmap)
{
-
+
Window xroot = RootWindow (display, gdk_screen_get_number (screen));
char *atom_names[] = {"_XROOTPMAP_ID", "ESETROOT_PMAP_ID"};
Atom atoms[G_N_ELEMENTS(atom_names)] = {0};
=== modified file 'src/greeterbackground.h'
--- src/greeterbackground.h 2014-08-31 17:45:52 +0000
+++ src/greeterbackground.h 2014-11-28 11:56:32 +0000
@@ -38,8 +38,6 @@
const gchar* path);
void greeter_background_save_xroot (GreeterBackground* background);
const GdkRectangle* greeter_background_get_active_monitor_geometry(GreeterBackground* background);
-void greeter_background_add_accel_group (GreeterBackground* background,
- GtkAccelGroup* group);
G_END_DECLS
=== modified file 'src/lightdm-gtk-greeter-fallback.css'
--- src/lightdm-gtk-greeter-fallback.css 2014-05-22 19:52:34 +0000
+++ src/lightdm-gtk-greeter-fallback.css 2014-11-28 11:56:32 +0000
@@ -10,3 +10,14 @@
{
padding: 1px;
}
+
+/* Used as "screen-capture" effect */
+#capture-splash.capture-triggered
+{
+ background: alpha(@theme_base_color, 0.5);
+}
+
+#screen
+{
+ background: transparent;
+}
=== modified file 'src/lightdm-gtk-greeter.c'
--- src/lightdm-gtk-greeter.c 2014-09-01 07:58:56 +0000
+++ src/lightdm-gtk-greeter.c 2014-11-28 11:56:32 +0000
@@ -63,6 +63,7 @@
/* Screen window */
static GtkOverlay *screen_overlay;
+static GtkAccelGroup *greeter_accel_group;
/* Login window */
static GtkWidget *login_window;
@@ -76,9 +77,10 @@
/* Panel */
static GtkWidget *panel_window, *menubar;
static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
- *layout_menuitem, *clock_menuitem, *host_menuitem;
+ *layout_menuitem, *clock_menuitem, *host_menuitem, *tools_menuitem;
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
+static GtkWidget *screenshot_menuitem;
static GtkWidget *clock_label, *session_badge;
static GtkMenu *session_menu, *language_menu, *layout_menu;
@@ -278,6 +280,18 @@
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
+/* Screen capture */
+static const gint SCREENSHOT_BLINK_DURATION = 300; /* Duration (in ms) of "screen capture" effect */
+static const gint SCREENSHOT_DEFAULT_MAX_COUNT = 10;
+
+static GtkWidget *screenshot_splash_widget = NULL;
+static guint screenshot_splash_finish_id = 0;
+
+static gint screenshot_max_count;
+void tools_screenshot_cb (GtkWidget *menuitem, gpointer userdata);
+static gint compare_file_info_dates (GFileInfo *a_info, GFileInfo *b_info);
+static gboolean take_screenshot (gint max_files_count);
+
/* Power indciator */
static void power_menu_cb (GtkWidget *menuitem, gpointer userdata);
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
@@ -1345,6 +1359,7 @@
g_hash_table_insert (builtin_items, "~layout", layout_menuitem);
g_hash_table_insert (builtin_items, "~host", host_menuitem);
g_hash_table_insert (builtin_items, "~clock", clock_menuitem);
+ g_hash_table_insert (builtin_items, "~tools", tools_menuitem);
g_hash_table_iter_init (&iter, builtin_items);
while (g_hash_table_iter_next (&iter, NULL, &iter_value))
@@ -1717,6 +1732,192 @@
menu_command_stop (a11y_reader_command);
}
+/* Taking screenshot */
+
+static gboolean
+screenshot_splash_timeout_cb (gpointer user_data)
+{
+ gtk_widget_hide (screenshot_splash_widget);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (screenshot_splash_widget), "capture-triggered");
+ screenshot_splash_finish_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+void
+tools_screenshot_cb (GtkWidget *menuitem, gpointer userdata)
+{
+ if (screenshot_max_count == 0)
+ return;
+
+ if (take_screenshot (screenshot_max_count))
+ {
+ /* TODO: Playing "capture" sound */
+
+ if (!screenshot_splash_widget)
+ {
+ screenshot_splash_widget = gtk_event_box_new ();
+ gtk_widget_set_name (screenshot_splash_widget, "capture-splash");
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (screenshot_splash_widget), TRUE);
+ gtk_overlay_add_overlay (screen_overlay, screenshot_splash_widget);
+ }
+
+ if (!screenshot_splash_finish_id)
+ {
+ gtk_widget_show (screenshot_splash_widget);
+ gtk_style_context_add_class (gtk_widget_get_style_context (screenshot_splash_widget), "capture-triggered");
+ screenshot_splash_finish_id = g_timeout_add (SCREENSHOT_BLINK_DURATION, screenshot_splash_timeout_cb, NULL);
+ }
+ }
+ else
+ {
+ /* TODO: Playing "error" sound */
+ }
+}
+
+static gint
+compare_file_info_dates (GFileInfo *a_info, GFileInfo *b_info)
+{
+ guint64 a = g_file_info_get_attribute_uint64 (a_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+ guint64 b = g_file_info_get_attribute_uint64 (b_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
+static gboolean
+take_screenshot (gint max_files_count)
+{
+ g_debug ("[Screenshot] Taking screenshot...");
+
+ if (max_files_count == 0)
+ {
+ g_debug ("[Screenshot] Aborting: max_files_count == 0");
+ return FALSE;
+ }
+
+ const gchar *tmp_dir_variable = g_getenv ("TMPDIR");
+ gchar *output_dir;
+ GError *error = NULL;
+ gboolean failed = FALSE;
+
+ const gint SCREENSHOT_DIR_MODE = 0700;
+ const gchar *SCREENSHOT_DIR_NAME = "lightdm-gtk-greeter-screenshots";
+
+ if (tmp_dir_variable)
+ output_dir = g_build_filename (tmp_dir_variable, SCREENSHOT_DIR_NAME, NULL);
+ else
+ /* "/var/tmp" is usually more persistent than "/tmp" */
+ output_dir = g_build_filename (G_DIR_SEPARATOR_S, "var", "tmp", SCREENSHOT_DIR_NAME, NULL);
+
+ if (g_mkdir_with_parents (output_dir, SCREENSHOT_DIR_MODE) == -1)
+ {
+ g_warning ("[Screenshot] Failed to create directory '%s': %s", output_dir, g_strerror (errno));
+ g_free (output_dir);
+ return FALSE;
+ }
+
+ GDateTime *now = g_date_time_new_now_local ();
+ gchar *output_name = now ? g_date_time_format (now, "screenshot_%F_%T.png") : g_strdup ("screenshot.png");
+ g_date_time_unref (now);
+
+ if (max_files_count > 0)
+ {
+ GFileEnumerator *enumerator;
+ GFile *parent = g_file_new_for_path (output_dir);
+ enumerator = g_file_enumerate_children (parent,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED,
+ G_FILE_QUERY_INFO_NONE,
+ NULL, &error);
+
+ if (!enumerator)
+ {
+ g_warning ("[Screenshot] Failed to enumerate screenshots directory: %s", error ? error->message : "unknown error");
+ g_clear_error (&error);
+ g_object_unref (parent);
+ g_free (output_name);
+ g_free (output_dir);
+ return FALSE;
+ }
+
+ gint files_count = 0;
+ GList *files = NULL;
+ GFileInfo *info;
+
+ while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)))
+ {
+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR &&
+ g_strcmp0 (g_file_info_get_name (info), output_name) != 0)
+ {
+ files = g_list_prepend (files, info);
+ files_count++;
+ }
+ else
+ g_object_unref (info);
+ }
+ g_file_enumerator_close (enumerator, NULL, NULL);
+ g_object_unref (enumerator);
+
+ g_debug ("[Screenshot] Directory items count: %d, limit: %d", files_count, max_files_count);
+
+ if (files_count >= max_files_count)
+ {
+ GList *iter;
+ files = g_list_sort (files, (GCompareFunc)compare_file_info_dates);
+
+ for (iter = g_list_nth (files, files_count - max_files_count); iter && !failed; iter = g_list_previous (iter))
+ {
+ GFile *file = g_file_get_child (parent, g_file_info_get_name (iter->data));
+ if (!g_file_delete (file, NULL, &error))
+ {
+ g_warning ("[Screenshot] Failed to delete old screenshot '%s': %s",
+ g_file_info_get_name (iter->data),
+ error ? error->message : "unknown error");
+ g_clear_error (&error);
+ failed = TRUE;
+ }
+ g_object_unref (file);
+ }
+ }
+ g_list_free_full (files, g_object_unref);
+ g_object_unref (parent);
+
+ if (failed)
+ {
+ g_free (output_name);
+ g_free (output_dir);
+ return FALSE;
+ }
+ }
+
+ /* Finally, taking screenshot */
+
+ GdkWindow *root = gdk_get_default_root_window ();
+ GdkPixbuf *screenshot = gdk_pixbuf_get_from_window (root, 0, 0, gdk_window_get_width (root), gdk_window_get_height (root));
+
+ if (!screenshot)
+ g_warning ("[Screenshot] gdk_pixbuf_get_from_window failed");
+ else
+ {
+ gchar *output_path = g_build_filename (output_dir, output_name, NULL);
+ if (!gdk_pixbuf_save (screenshot, output_path, "png", &error, NULL))
+ {
+ g_warning ("[Screenshot] Failed to save image as '%s': %s", output_path, error ? error->message : "unknown error");
+ g_clear_error (&error);
+ failed = TRUE;
+ }
+ else
+ g_debug ("[Screenshot] Image saved as '%s'", output_path);
+
+ g_object_unref (screenshot);
+ g_free (output_path);
+ }
+
+ g_free (output_name);
+ g_free (output_dir);
+
+ return screenshot && !failed;
+}
+
/* Power indicator */
static void
@@ -2400,32 +2601,25 @@
}
static GdkFilterReturn
-focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
+wm_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
{
XEvent* xevent = (XEvent*)gxevent;
- GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ?
- gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL;
if (xevent->type == MapNotify)
{
- Window xwin = xevent->xmap.window;
- Window keyboard_xid = 0;
- GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
- GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin);
+ GdkDisplay *display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
+ GdkWindow *win = gdk_x11_window_foreign_new_for_display (display, xevent->xmap.window);
GdkWindowTypeHint win_type = gdk_window_get_type_hint (win);
- /* Check to see if this window is our onboard window, since we don't want to focus it. */
- if (keyboard_win)
- keyboard_xid = gdk_x11_window_get_xid (keyboard_win);
-
- if (xwin != keyboard_xid
- && win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP
- && win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
- {
+/* if (win_type != GDK_WINDOW_TYPE_HINT_COMBO &&
+ win_type != GDK_WINDOW_TYPE_HINT_MENU &&
+ win_type != GDK_WINDOW_TYPE_HINT_POPUP_MENU &&
+ win_type != GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU &&
+ win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP &&
+ win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
+*/
+ if (win_type == GDK_WINDOW_TYPE_HINT_DESKTOP ||
+ win_type == GDK_WINDOW_TYPE_HINT_DIALOG)
gdk_window_focus (win, GDK_CURRENT_TIME);
- /* Make sure to keep keyboard above */
- if (keyboard_win)
- gdk_window_raise (keyboard_win);
- }
}
else if (xevent->type == UnmapNotify)
{
@@ -2434,12 +2628,25 @@
XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to);
if (revert_to == RevertToNone)
- {
- gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME);
- /* Make sure to keep keyboard above */
- if (keyboard_win)
- gdk_window_raise (keyboard_win);
- }
+ gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (screen_overlay)), GDK_CURRENT_TIME);
+ }
+ return GDK_FILTER_CONTINUE;
+}
+
+static GdkFilterReturn
+accelerators_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
+{
+ XKeyEvent* keyevent = (XKeyEvent*)gxevent;
+ if (keyevent->type == KeyPress)
+ {
+ KeySym accel_key = XLookupKeysym (keyevent, 0);
+ GdkModifierType accel_mods = keyevent->state & ~(Mod2Mask | Mod5Mask | LockMask);
+ gchar *accel_name = gtk_accelerator_name (accel_key, (accel_mods & gtk_accelerator_get_default_mod_mask ()));
+ GQuark accel_quark = g_quark_from_string (accel_name);
+ g_free (accel_name);
+
+ if (gtk_accel_group_activate (greeter_accel_group, accel_quark, G_OBJECT (screen_overlay), accel_key, accel_mods))
+ return GDK_FILTER_REMOVE;
}
return GDK_FILTER_CONTINUE;
}
@@ -2590,6 +2797,7 @@
/* Screen window */
screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay"));
+ greeter_accel_group = GTK_ACCEL_GROUP (gtk_builder_get_object (builder, "greeter_accel_group"));
/* Login window */
login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window"));
@@ -2605,18 +2813,27 @@
/* Panel window*/
panel_window = GTK_WIDGET (gtk_builder_get_object (builder, "panel_window"));
menubar = GTK_WIDGET (gtk_builder_get_object (builder, "menubar"));
+
session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem"));
session_menu = GTK_MENU (gtk_builder_get_object (builder, "session_menu"));
+
language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem"));
language_menu = GTK_MENU (gtk_builder_get_object (builder, "language_menu"));
+
a11y_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem"));
contrast_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "high_contrast_menuitem"));
font_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "large_font_menuitem"));
keyboard_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "keyboard_menuitem"));
reader_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "reader_menuitem"));
+
power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem"));
+
layout_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "layout_menuitem"));
layout_menu = GTK_MENU (gtk_builder_get_object (builder, "layout_menu"));
+
+ tools_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "tools_menuitem"));
+ screenshot_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "screenshot_menuitem"));
+
clock_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "clock_menuitem"));
host_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "host_menuitem"));
@@ -2637,6 +2854,7 @@
gtk_accel_map_add_entry ("<Login>/a11y/keyboard", GDK_KEY_F3, 0);
gtk_accel_map_add_entry ("<Login>/a11y/reader", GDK_KEY_F4, 0);
gtk_accel_map_add_entry ("<Login>/power/shutdown", GDK_KEY_F4, GDK_MOD1_MASK);
+ gtk_accel_map_add_entry ("<Login>/tools/screenshot", GDK_KEY_Print, 0);
#ifdef START_INDICATOR_SERVICES
init_indicators (config, &indicator_pid, &spi_pid);
@@ -2829,6 +3047,17 @@
gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL);
}
+ /* Screen capture */
+ screenshot_max_count = g_key_file_get_integer (config, "greeter", "max-screenshots-count", &error);
+ if (error)
+ {
+ if (error->code == G_KEY_FILE_ERROR_INVALID_VALUE)
+ g_warning ("[Configuration] Invalid 'max-screenshots-count' value, using default: %d", SCREENSHOT_DEFAULT_MAX_COUNT);
+ screenshot_max_count = SCREENSHOT_DEFAULT_MAX_COUNT;
+ g_clear_error (&error);
+ }
+ gtk_widget_set_visible (screenshot_menuitem, screenshot_max_count != 0);
+
/* A bit of CSS */
GdkRGBA lightdm_gtk_greeter_override_defaults;
css_provider = gtk_css_provider_new ();
@@ -2885,9 +3114,6 @@
}
g_strfreev (config_groups);
- greeter_background_add_accel_group (greeter_background, GTK_ACCEL_GROUP (gtk_builder_get_object (builder, "a11y_accelgroup")));
- greeter_background_add_accel_group (greeter_background, GTK_ACCEL_GROUP (gtk_builder_get_object (builder, "power_accelgroup")));
-
greeter_background_connect (greeter_background, gdk_screen_get_default ());
if (lightdm_greeter_get_hide_users_hint (greeter))
@@ -2956,10 +3182,12 @@
}
g_strfreev (values);
- /* focus fix (source: unity-greeter) */
- GdkWindow* root_window = gdk_get_default_root_window ();
+ GdkWindow *root_window = gdk_get_default_root_window ();
gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK);
- gdk_window_add_filter (root_window, focus_upon_map, NULL);
+ /* There is no window manager, so we need to implement some of its functionality */
+ gdk_window_add_filter (root_window, wm_window_filter, NULL);
+ /* Use "manual" accelerators control instead of passing accel groups to GreeterBackground's windows */
+ gdk_window_add_filter (gtk_widget_get_window (GTK_WIDGET (screen_overlay)), accelerators_window_filter, NULL);
gtk_widget_show (GTK_WIDGET (screen_overlay));
=== modified file 'src/lightdm-gtk-greeter.glade'
--- src/lightdm-gtk-greeter.glade 2014-09-24 17:41:33 +0000
+++ src/lightdm-gtk-greeter.glade 2014-11-28 11:56:32 +0000
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
- <requires lib="gtk+" version="3.4"/>
+ <requires lib="gtk+" version="3.8"/>
<requires lib="greeter_menu_bar" version="1.0"/>
- <object class="GtkAccelGroup" id="a11y_accelgroup"/>
- <object class="GtkAccelGroup" id="power_accelgroup"/>
+ <object class="GtkAccelGroup" id="greeter_accel_group"/>
<object class="GtkEventBox" id="panel_window">
<property name="name">panel_window</property>
<property name="visible">True</property>
@@ -26,12 +25,13 @@
<object class="GtkMenu" id="power_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="accel_group">power_accelgroup</property>
+ <property name="accel_group">greeter_accel_group</property>
<child>
<object class="GtkMenuItem" id="suspend_menuitem">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Suspend</property>
+ <property name="use_underline">True</property>
<signal name="activate" handler="suspend_cb" swapped="no"/>
</object>
</child>
@@ -40,6 +40,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hibernate</property>
+ <property name="use_underline">True</property>
<signal name="activate" handler="hibernate_cb" swapped="no"/>
</object>
</child>
@@ -48,16 +49,17 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Restart...</property>
+ <property name="use_underline">True</property>
<signal name="activate" handler="restart_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="shutdown_menuitem">
- <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="accel_path"><Login>/power/shutdown</property>
<property name="label" translatable="yes">Shut Down...</property>
+ <property name="use_underline">True</property>
<signal name="activate" handler="shutdown_cb" swapped="no"/>
</object>
</child>
@@ -74,30 +76,29 @@
<object class="GtkMenu" id="a11y_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="accel_group">a11y_accelgroup</property>
+ <property name="accel_group">greeter_accel_group</property>
<child>
<object class="GtkCheckMenuItem" id="large_font_menuitem">
- <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="accel_path"><Login>/a11y/font</property>
<property name="label" translatable="yes">Large Font</property>
+ <property name="use_underline">True</property>
<signal name="toggled" handler="a11y_font_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="high_contrast_menuitem">
- <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="accel_path"><Login>/a11y/contrast</property>
<property name="label" translatable="yes">High Contrast</property>
+ <property name="use_underline">True</property>
<signal name="toggled" handler="a11y_contrast_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckMenuItem" id="keyboard_menuitem">
- <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="accel_path"><Login>/a11y/keyboard</property>
@@ -108,7 +109,6 @@
</child>
<child>
<object class="GtkCheckMenuItem" id="reader_menuitem">
- <property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="accel_path"><Login>/a11y/reader</property>
@@ -126,7 +126,6 @@
<property name="name">language_menuitem</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label">[language_code]</property>
<child type="submenu">
<object class="GtkMenu" id="language_menu">
<property name="visible">True</property>
@@ -153,7 +152,6 @@
<property name="name">layout_menuitem</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="label">[layout]</property>
<child type="submenu">
<object class="GtkMenu" id="layout_menu">
<property name="visible">True</property>
@@ -163,6 +161,30 @@
</object>
</child>
<child>
+ <object class="GtkMenuItem" id="tools_menuitem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_underline">True</property>
+ <child type="submenu">
+ <object class="GtkMenu" id="tools_menu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="accel_group">greeter_accel_group</property>
+ <child>
+ <object class="GtkMenuItem" id="screenshot_menuitem">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="accel_path"><Login>/tools/screenshot</property>
+ <property name="label" translatable="yes">Take screenshot</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="tools_screenshot_cb" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
<object class="GtkSeparatorMenuItem" id="clock_menuitem">
<property name="name">clock_menuitem</property>
<property name="can_focus">False</property>
@@ -219,6 +241,7 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
+ <property name="width">1</property>
<property name="height">2</property>
</packing>
</child>
@@ -237,6 +260,8 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
@@ -250,6 +275,8 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
</object>
@@ -328,10 +355,11 @@
<property name="vexpand">True</property>
<signal name="get-child-position" handler="screen_overlay_get_child_position_cb" swapped="no"/>
<child>
- <object class="GtkBox" id="screen-child">
+ <object class="GtkEventBox" id="screen-child">
+ <property name="name">screen-child</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <property name="visible_window">False</property>
<child>
<placeholder/>
</child>
@@ -401,6 +429,7 @@
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
+ <property name="width">1</property>
<property name="height">3</property>
</packing>
</child>
@@ -426,6 +455,8 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
@@ -442,6 +473,8 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
<child>
@@ -463,6 +496,8 @@
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
</packing>
</child>
</object>
Follow ups