60
61
static gchar *state_filename;
61
62
static void save_state_file (void);
63
/* Login Window Widgets */
64
static GtkWindow *login_window;
65
static GtkImage *user_image;
66
static GtkComboBox *user_combo;
67
static GtkEntry *username_entry, *password_entry;
68
static GtkLabel *message_label;
69
static GtkInfoBar *info_bar;
70
static GtkButton *cancel_button, *login_button;
73
static GtkWindow *panel_window;
74
static GtkWidget *menubar;
75
static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
76
*layout_menuitem, *clock_menuitem, *host_menuitem;
77
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
78
static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
79
static GtkWidget *clock_label, *session_badge;
80
static GtkMenu *session_menu, *language_menu, *layout_menu;
65
static GtkOverlay *screen_overlay;
68
static GtkWidget *login_window;
69
static GtkImage *user_image;
70
static GtkComboBox *user_combo;
71
static GtkEntry *username_entry, *password_entry;
72
static GtkLabel *message_label;
73
static GtkInfoBar *info_bar;
74
static GtkButton *cancel_button, *login_button;
77
static GtkWidget *panel_window, *menubar;
78
static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem,
79
*layout_menuitem, *clock_menuitem, *host_menuitem;
80
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
81
static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
82
static GtkWidget *clock_label, *session_badge;
83
static GtkMenu *session_menu, *language_menu, *layout_menu;
86
static GtkWidget *power_window;
87
static GtkButton *power_ok_button, *power_cancel_button;
88
static GtkLabel *power_title, *power_text;
89
static GtkImage *power_icon;
91
static const gchar *POWER_WINDOW_DATA_LOOP = "power-window-loop"; /* <GMainLoop*> */
92
static const gchar *POWER_WINDOW_DATA_RESPONSE = "power-window-response"; /* <GtkResponseType> */
94
static gboolean show_power_prompt (const gchar *action, const gchar* icon, const gchar* title, const gchar* message);
95
void power_button_clicked_cb (GtkButton *button, gpointer user_data);
96
gboolean power_window_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
98
/* Handling window position */
95
112
DimensionPosition x, y;
113
/* Flag to use width and height fileds */
115
DimensionPosition width, height;
118
static WindowPosition* key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value);
98
119
/* Function translate user defined coordinates to absolute value */
99
120
static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window);
100
static const WindowPosition WINDOW_POS_CENTER = {.x = { 50, +1, TRUE, 0}, .y = { 50, +1, TRUE, 0}};
101
static const WindowPosition WINDOW_POS_TOP_LEFT = {.x = { 0, +1, FALSE, -1}, .y = { 0, +1, FALSE, -1}};
102
static const WindowPosition ONBOARD_WINDOW_POS = {.x = { 50, +1, TRUE, 0}, .y = { 0, -1, FALSE, +1}};
103
static const WindowPosition ONBOARD_WINDOW_SIZE = {.x = {610, 0, FALSE, 0}, .y = {210, 0, FALSE, 0}};
104
static WindowPosition main_window_pos;
105
static WindowPosition panel_window_pos;
107
static gchar *default_font_name, *default_theme_name, *default_icon_theme_name;
121
gboolean screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data);
123
static const gchar *WINDOW_DATA_POSITION = "window-position"; /* <WindowPosition*> */
125
/* Some default positions */
126
static const WindowPosition WINDOW_POS_CENTER = {.x = { 50, +1, TRUE, 0}, .y = { 50, +1, TRUE, 0}, .use_size = FALSE};
127
static const WindowPosition KEYBOARD_POSITION = {.x = { 50, +1, TRUE, 0}, .y = { 0, -1, FALSE, +1}, .use_size = TRUE,
128
.width = {50, 0, TRUE, 0}, .height = {25, 0, TRUE, 0}};
131
static gboolean key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value);
108
134
static gchar *clock_format;
135
static gboolean clock_timeout_thread (void);
138
static gboolean message_label_is_empty (void);
139
static void set_message_label (LightDMMessageType type, const gchar *text);
109
142
static GdkPixbuf *default_user_pixbuf = NULL;
110
143
static gchar *default_user_icon = "avatar-default";
144
static void set_user_image (const gchar *username);
146
/* External command (keyboard, reader) */
192
230
static const gchar *PANEL_ITEM_DATA_INDEX = "panel-item-data-index";
194
232
#ifdef HAVE_LIBINDICATOR
195
static const gchar *INDICATOR_ITEM_DATA_OBJECT = "indicator-item-data-object";
196
static const gchar *INDICATOR_ITEM_DATA_ENTRY = "indicator-item-data-entry";
197
static const gchar *INDICATOR_ITEM_DATA_BOX = "indicator-item-data-box";
198
static const gchar *INDICATOR_DATA_MENUITEMS = "indicator-data-menuitems";
202
key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value)
204
GError* error = NULL;
205
gboolean result = g_key_file_get_boolean (key_file, group_name, key, &error);
208
g_clear_error (&error);
209
return default_value;
233
static const gchar *INDICATOR_ITEM_DATA_OBJECT = "indicator-item-data-object"; /* <IndicatorObject*> */
234
static const gchar *INDICATOR_ITEM_DATA_ENTRY = "indicator-item-data-entry"; /* <IndicatorObjectEntry*> */
235
static const gchar *INDICATOR_ITEM_DATA_BOX = "indicator-item-data-box"; /* <GtkBox*> */
236
static const gchar *INDICATOR_DATA_MENUITEMS = "indicator-data-menuitems"; /* <GHashTable*> */
239
static const gchar *LANGUAGE_DATA_CODE = "language-code"; /* <gchar*> e.g. "de_DE.UTF-8" */
240
static const gchar *SESSION_DATA_KEY = "session-key"; /* <gchar*> session name */
242
/* Layout indicator */
243
#ifdef HAVE_LIBXKLAVIER
244
static XklEngine *xkl_engine;
245
static const gchar *LAYOUT_DATA_GROUP = "layout-group"; /* <gchar*> */
247
static const gchar *LAYOUT_DATA_NAME = "layout-name"; /* <gchar*> */
249
static const gchar *LAYOUT_DATA_LABEL = "layout-label"; /* <gchar*> e.g. "English (US)" */
251
static gboolean panel_item_enter_notify_cb (GtkWidget *widget, GdkEvent *event, gpointer enter);
252
static void panel_add_item (GtkWidget *widget, gint index, GreeterPanelItemType item_type);
253
static gboolean menu_item_accel_closure_cb (GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier, gpointer data);
254
/* Maybe unnecessary (in future) trick to enable accelerators for hidden/detached menu items */
255
static void reassign_menu_item_accel (GtkWidget *item);
257
#ifdef START_INDICATOR_SERVICES
258
static void init_indicators (GKeyFile* config, GPid* indicator_pid, GPid* spi_pid);
260
static void init_indicators (GKeyFile* config);
263
static void layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data);
264
static void update_layouts_menu (void);
265
static void update_layouts_menu_state (void);
266
#ifdef HAVE_LIBXKLAVIER
267
static void xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group, gboolean restore, gpointer user_data);
268
static void xkl_config_changed_cb (XklEngine *engine, gpointer user_data);
269
static GdkFilterReturn xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer data);
273
static gchar *default_font_name,
275
*default_icon_theme_name;
276
void a11y_font_cb (GtkCheckMenuItem *item);
277
void a11y_contrast_cb (GtkCheckMenuItem *item);
278
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
279
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
281
/* Power indciator */
282
static void power_menu_cb (GtkWidget *menuitem, gpointer userdata);
283
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
284
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
285
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
286
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
215
291
save_state_file (void)
318
show_power_prompt (const gchar *action, const gchar* icon, const gchar* title, const gchar* message)
320
gchar *new_message = NULL;
322
/* Check if there are still users logged in, count them and if so, display a warning */
323
gint logged_in_users = 0;
324
GList *items = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
326
for (item = items; item; item = item->next)
328
LightDMUser *user = item->data;
329
if (lightdm_user_get_logged_in (user))
333
if (logged_in_users > 0)
335
gchar *warning = g_strdup_printf (ngettext ("Warning: There is still %d user logged in.",
336
"Warning: There are still %d users logged in.",
339
message = new_message = g_markup_printf_escaped ("<b>%s</b>\n%s", warning, message);
343
gchar *dialog_name = g_strconcat (action, "_dialog", NULL);
344
gchar *button_name = g_strconcat (action, "_button", NULL);
346
gtk_widget_set_name (power_window, dialog_name);
347
gtk_widget_set_name (GTK_WIDGET (power_ok_button), button_name);
348
gtk_button_set_label (power_ok_button, title);
349
gtk_label_set_label (power_title, title);
350
gtk_label_set_markup (power_text, message);
351
gtk_image_set_from_icon_name (power_icon, icon, GTK_ICON_SIZE_DIALOG);
353
g_free (button_name);
354
g_free (dialog_name);
355
g_free (new_message);
357
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
358
g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_LOOP, loop);
359
g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE, GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
361
GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay))));
362
gboolean session_enabled = gtk_widget_get_sensitive (session_menuitem);
363
gboolean language_enabled = gtk_widget_get_sensitive (language_menuitem);
365
gtk_widget_set_sensitive (power_menuitem, FALSE);
366
gtk_widget_set_sensitive (session_menuitem, FALSE);
367
gtk_widget_set_sensitive (language_menuitem, FALSE);
368
gtk_widget_hide (login_window);
369
gtk_widget_show (power_window);
370
gtk_widget_grab_focus (GTK_WIDGET (power_ok_button));
372
g_main_loop_run (loop);
373
GtkResponseType response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE));
374
g_main_loop_unref (loop);
376
gtk_widget_hide (power_window);
377
gtk_widget_show (login_window);
378
gtk_widget_set_sensitive (power_menuitem, TRUE);
379
gtk_widget_set_sensitive (session_menuitem, session_enabled);
380
gtk_widget_set_sensitive (language_menuitem, language_enabled);
383
gtk_widget_grab_focus (focused);
385
return response == GTK_RESPONSE_YES;
389
power_button_clicked_cb (GtkButton *button, gpointer user_data)
391
GMainLoop *loop = g_object_get_data (G_OBJECT (power_window), POWER_WINDOW_DATA_LOOP);
392
if (g_main_loop_is_running (loop))
393
g_main_loop_quit (loop);
395
g_object_set_data (G_OBJECT (power_window), POWER_WINDOW_DATA_RESPONSE,
396
GINT_TO_POINTER (button == power_ok_button ? GTK_RESPONSE_YES : GTK_RESPONSE_CANCEL));
400
power_window_key_press_event_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
402
if (event->keyval == GDK_KEY_Escape)
404
power_button_clicked_cb (power_cancel_button, NULL);
410
/* Handling window position */
413
read_position_from_str (const gchar *s, DimensionPosition *x)
417
gchar **parts = g_strsplit (s, ",", 2);
420
p.value = g_ascii_strtoll (parts[0], &end, 10);
421
p.percentage = end && end[0] == '%';
422
p.sign = (p.value < 0 || (p.value == 0 && parts[0][0] == '-')) ? -1 : +1;
425
if (g_strcmp0(parts[1], "start") == 0)
427
else if (g_strcmp0(parts[1], "center") == 0)
429
else if (g_strcmp0(parts[1], "end") == 0)
432
p.anchor = p.sign > 0 ? -1 : +1;
441
static WindowPosition*
442
key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value)
444
WindowPosition* pos = g_new0 (WindowPosition, 1);
445
gchar *value = g_key_file_get_value (key_file, group_name, key, NULL);
447
*pos = *default_value;
452
gchar *y = strchr (value, ' ');
456
if (read_position_from_str (x, &pos->x))
457
/* If there is no y-part then y = x */
458
if (!y || !read_position_from_str (y, &pos->y))
461
gchar *size_delim = strchr (y ? y : x, ';');
464
gchar *x = size_delim + 1;
465
if (read_position_from_str (x, &pos->width))
470
if (!y || !read_position_from_str (y, &pos->height))
471
if (!default_value->use_size)
472
pos->height = pos->width;
473
pos->use_size = TRUE;
484
get_absolute_position (const DimensionPosition *p, gint screen, gint window)
486
gint x = p->percentage ? (screen*p->value)/100 : p->value;
487
x = p->sign < 0 ? screen - x : x;
490
else if (p->anchor == 0)
493
if (x < 0) /* Offscreen: left/top */
495
else if (x + window > screen) /* Offscreen: right/bottom */
496
return screen - window;
502
screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data)
504
const WindowPosition *pos = g_object_get_data (G_OBJECT (widget), WINDOW_DATA_POSITION);
508
gint screen_width = gtk_widget_get_allocated_width (overlay);
509
gint screen_height = gtk_widget_get_allocated_height (overlay);
513
allocation->width = get_absolute_position (&pos->width, screen_width, 0);
514
allocation->height = get_absolute_position (&pos->height, screen_height, 0);
518
gtk_widget_get_preferred_width (widget, NULL, &allocation->width);
519
gtk_widget_get_preferred_height (widget, NULL, &allocation->height);
522
allocation->x = get_absolute_position (&pos->x, screen_width, allocation->width);
523
allocation->y = get_absolute_position (&pos->y, screen_height, allocation->height);
525
/* Do not overlap panel window */
526
gint panel_height = gtk_widget_get_allocated_height (panel_window);
527
if (panel_height && gtk_widget_get_visible (panel_window))
529
GtkAlign valign = gtk_widget_get_valign (panel_window);
530
if (valign == GTK_ALIGN_START && allocation->y < panel_height)
531
allocation->y = panel_height;
532
else if (valign == GTK_ALIGN_END && screen_height - allocation->y - allocation->height < panel_height)
533
allocation->y = screen_height - allocation->height - panel_height;
542
key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value)
544
GError* error = NULL;
545
gboolean result = g_key_file_get_boolean (key_file, group_name, key, &error);
548
g_clear_error (&error);
549
return default_value;
557
clock_timeout_thread (void)
560
struct tm * timeinfo;
565
timeinfo = localtime (&rawtime);
567
strftime (time_str, 50, clock_format, timeinfo);
568
markup = g_markup_printf_escaped ("<b>%s</b>", time_str);
569
if (g_strcmp0 (markup, gtk_label_get_label (GTK_LABEL (clock_label))) != 0)
570
gtk_label_set_markup (GTK_LABEL (clock_label), markup);
579
message_label_is_empty (void)
581
return gtk_label_get_text (message_label)[0] == '\0';
585
set_message_label (LightDMMessageType type, const gchar *text)
587
if (type == LIGHTDM_MESSAGE_TYPE_INFO)
588
gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_INFO);
590
gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_ERROR);
591
gtk_label_set_text (message_label, text);
592
gtk_widget_set_visible (GTK_WIDGET (info_bar), text && text[0]);
598
set_user_image (const gchar *username)
601
LightDMUser *user = NULL;
602
GdkPixbuf *image = NULL;
603
GError *error = NULL;
605
if (!gtk_widget_get_visible (GTK_WIDGET (user_image)))
609
user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
613
path = lightdm_user_get_image (user);
616
image = gdk_pixbuf_new_from_file_at_scale (path, 80, 80, FALSE, &error);
619
gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), image);
620
g_object_unref (image);
625
g_warning ("Failed to load user image: %s", error->message);
626
g_clear_error (&error);
631
if (default_user_pixbuf)
632
gtk_image_set_from_pixbuf (GTK_IMAGE (user_image), default_user_pixbuf);
634
gtk_image_set_from_icon_name (GTK_IMAGE (user_image), default_user_icon, GTK_ICON_SIZE_DIALOG);
239
637
/* MenuCommand */
241
639
static MenuCommand*
242
640
menu_command_parse (const gchar *value, GtkWidget *menu_item)
244
return menu_command_parse_extended (value, menu_item, NULL, NULL, NULL);
642
return menu_command_parse_extended (value, menu_item, NULL, NULL);
247
645
static MenuCommand*
248
menu_command_parse_extended (const gchar *value, GtkWidget *menu_item,
249
const gchar *xid_supported, const gchar *xid_arg,
250
const WindowPosition *size)
646
menu_command_parse_extended (const gchar *value, /* String to parse */
647
GtkWidget *menu_item, /* Menu item to connect */
648
const gchar *xid_app, /* Program that have "xembed" mode support */
649
const gchar *xid_arg) /* Argument that must be added to command line */
405
797
save_state_file ();
803
is_valid_session (GList* items, const gchar* session)
805
for (; items; items = g_list_next (items))
806
if (g_strcmp0 (session, lightdm_session_get_key (items->data)) == 0)
814
return g_strdup (current_session);
818
set_session (const gchar *session)
820
gchar *last_session = NULL;
821
GList *sessions = lightdm_get_sessions ();
824
if (!session || !is_valid_session (sessions, session))
826
/* previous session */
827
last_session = g_key_file_get_value (state, "greeter", "last-session", NULL);
828
if (last_session && g_strcmp0 (session, last_session) != 0 &&
829
is_valid_session (sessions, last_session))
830
session = last_session;
834
const gchar* default_session = lightdm_greeter_get_default_session_hint (greeter);
835
if (g_strcmp0 (session, default_session) != 0 &&
836
is_valid_session (sessions, default_session))
837
session = default_session;
838
/* first in the sessions list */
840
session = lightdm_session_get_key (sessions->data);
847
if (gtk_widget_get_visible (session_menuitem))
849
GList *menu_iter = NULL;
850
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (session_menu));
853
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
854
if (g_strcmp0 (session, g_object_get_data (G_OBJECT (menu_iter->data), SESSION_DATA_KEY)) == 0)
856
/* Set menuitem-image to session-badge */
857
GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
858
gchar* session_name = g_ascii_strdown (session, -1);
859
gchar* icon_name = g_strdup_printf ("%s_badge-symbolic", session_name);
860
g_free (session_name);
861
if (gtk_icon_theme_has_icon (icon_theme, icon_name))
862
gtk_image_set_from_icon_name (GTK_IMAGE (session_badge), icon_name, GTK_ICON_SIZE_MENU);
864
gtk_image_set_from_icon_name (GTK_IMAGE (session_badge), "document-properties-symbolic", GTK_ICON_SIZE_MENU);
870
menu_iter = menu_items;
873
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_iter->data), TRUE);
876
g_free (current_session);
877
current_session = g_strdup (session);
878
g_free (last_session);
882
session_selected_cb (GtkMenuItem *menuitem, gpointer user_data)
884
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)))
885
set_session (g_object_get_data (G_OBJECT (menuitem), SESSION_DATA_KEY));
889
/* Session language */
894
GList *menu_items, *menu_iter;
896
/* if the user manually selected a language, use it */
897
if (current_language)
898
return g_strdup (current_language);
900
menu_items = gtk_container_get_children (GTK_CONTAINER (language_menu));
901
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
903
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_iter->data)))
904
return g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
911
set_language (const gchar *language)
913
const gchar *default_language = NULL;
914
GList *menu_items, *menu_iter;
916
if (!gtk_widget_get_visible (language_menuitem))
918
g_free (current_language);
919
current_language = g_strdup (language);
923
menu_items = gtk_container_get_children (GTK_CONTAINER (language_menu));
927
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
931
s = g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
932
matched = g_strcmp0 (s, language) == 0;
936
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_iter->data), TRUE);
937
g_free (current_language);
938
current_language = g_strdup (language);
939
gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem),language);
945
/* If failed to find this language, then try the default */
946
if (lightdm_get_language ())
948
default_language = lightdm_language_get_code (lightdm_get_language ());
949
gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), default_language);
951
if (default_language && g_strcmp0 (default_language, language) != 0)
952
set_language (default_language);
953
/* If all else fails, just use the first language from the menu */
956
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next (menu_iter))
958
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_iter->data)))
960
gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE)));
968
language_selected_cb (GtkMenuItem *menuitem, gpointer user_data)
970
if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)))
972
gchar *language = g_object_get_data (G_OBJECT (menuitem), LANGUAGE_DATA_CODE);
973
set_language (language);
977
/* Pending questions */
409
980
pam_message_finalize (PAMConversationMessage *message)
412
983
g_free (message);
987
process_prompts (LightDMGreeter *greeter)
989
if (!pending_questions)
992
/* always allow the user to change username again */
993
gtk_widget_set_sensitive (GTK_WIDGET (username_entry), TRUE);
994
gtk_widget_set_sensitive (GTK_WIDGET (password_entry), TRUE);
996
/* Special case: no user selected from list, so PAM asks us for the user
997
* via a prompt. For that case, use the username field */
998
if (!prompted && pending_questions && !pending_questions->next &&
999
((PAMConversationMessage *) pending_questions->data)->is_prompt &&
1000
((PAMConversationMessage *) pending_questions->data)->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET &&
1001
gtk_widget_get_visible ((GTK_WIDGET (username_entry))) &&
1002
lightdm_greeter_get_authentication_user (greeter) == NULL)
1005
prompt_active = TRUE;
1006
gtk_widget_grab_focus (GTK_WIDGET (username_entry));
1007
gtk_widget_show (GTK_WIDGET (password_entry));
1011
while (pending_questions)
1013
PAMConversationMessage *message = (PAMConversationMessage *) pending_questions->data;
1014
pending_questions = g_slist_remove (pending_questions, (gconstpointer) message);
1016
if (!message->is_prompt)
1018
/* FIXME: this doesn't show multiple messages, but that was
1019
* already the case before. */
1020
set_message_label (message->type.message, message->text);
1024
gtk_widget_show (GTK_WIDGET (password_entry));
1025
gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1026
gtk_entry_set_text (password_entry, "");
1027
gtk_entry_set_visibility (password_entry, message->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET);
1028
if (message_label_is_empty () && password_prompted)
1030
/* No message was provided beforehand and this is not the
1031
* first password prompt, so use the prompt as label,
1032
* otherwise the user will be completely unclear of what
1033
* is going on. Actually, the fact that prompt messages are
1034
* not shown is problematic in general, especially if
1035
* somebody uses a custom PAM module that wants to ask
1036
* something different. */
1037
gchar *str = message->text;
1038
if (g_str_has_suffix (str, ": "))
1039
str = g_strndup (str, strlen (str) - 2);
1040
else if (g_str_has_suffix (str, ":"))
1041
str = g_strndup (str, strlen (str) - 1);
1042
set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, str);
1043
if (str != message->text)
1046
gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1048
password_prompted = TRUE;
1049
prompt_active = TRUE;
1051
/* If we have more stuff after a prompt, assume that other prompts are pending,
1057
/* Panel and indicators */
416
1060
panel_item_enter_notify_cb (GtkWidget *widget, GdkEvent *event, gpointer enter)
836
is_valid_session (GList* items, const gchar* session)
838
for (; items; items = g_list_next (items))
839
if (g_strcmp0 (session, lightdm_session_get_key (items->data)) == 0)
847
return g_strdup (current_session);
851
set_session (const gchar *session)
853
gchar *last_session = NULL;
854
GList *sessions = lightdm_get_sessions ();
857
if (!session || !is_valid_session (sessions, session))
859
/* previous session */
860
last_session = g_key_file_get_value (state, "greeter", "last-session", NULL);
861
if (last_session && g_strcmp0 (session, last_session) != 0 &&
862
is_valid_session (sessions, last_session))
863
session = last_session;
1479
/* Layout indicator */
1482
layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data)
1484
if (gtk_check_menu_item_get_active (menuitem))
1486
#ifdef HAVE_LIBXKLAVIER
1487
gint group = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP));
1488
xkl_engine_lock_group (xkl_engine, group);
1490
const gchar *name = g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_NAME);
1492
for (item = lightdm_get_layouts (); item; item = g_list_next (item))
1494
if (g_strcmp0 (name, lightdm_layout_get_name (item->data)) == 0)
1496
lightdm_set_layout (item->data);
1497
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
1498
g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_LABEL));
1507
update_layouts_menu (void)
1509
#ifdef HAVE_LIBXKLAVIER
1510
XklConfigRegistry *registry;
1511
XklConfigRec *config;
1512
XklConfigItem *config_item;
1513
GSList *menu_group = NULL;
1516
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
1517
(GDestroyNotify)gtk_widget_destroy);
1519
config = xkl_config_rec_new ();
1520
if (!xkl_config_rec_get_from_server (config, xkl_engine))
1522
g_object_unref (config);
1523
g_warning ("Failed to get Xkl configuration from server");
1527
config_item = xkl_config_item_new ();
1528
registry = xkl_config_registry_get_instance (xkl_engine);
1529
xkl_config_registry_load (registry, FALSE);
1531
for (i = 0; config->layouts[i] != NULL; ++i)
1533
const gchar *layout = config->layouts[i] ? config->layouts[i] : "";
1534
const gchar *variant = config->variants[i] ? config->variants[i] : "";
1535
gchar *label = strlen (variant) > 0 ? g_strdup_printf ("%s_%s", layout, variant) : g_strdup (layout);
1537
GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
1538
menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
1540
g_snprintf (config_item->name, sizeof (config_item->name), "%s", variant);
1541
if (xkl_config_registry_find_variant (registry, layout, config_item))
1542
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
867
const gchar* default_session = lightdm_greeter_get_default_session_hint (greeter);
868
if (g_strcmp0 (session, default_session) != 0 &&
869
is_valid_session (sessions, default_session))
870
session = default_session;
871
/* first in the sessions list */
873
session = lightdm_session_get_key (sessions->data);
1545
g_snprintf (config_item->name, sizeof (config_item->name), "%s", layout);
1546
if (xkl_config_registry_find_layout (registry, config_item))
1547
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
880
if (gtk_widget_get_visible (session_menuitem))
882
GList *menu_iter = NULL;
883
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (session_menu));
886
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
887
if (g_strcmp0 (session, g_object_get_data (G_OBJECT (menu_iter->data), SESSION_DATA_KEY)) == 0)
889
/* Set menuitem-image to session-badge */
890
GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
891
gchar* session_name = g_ascii_strdown (session, -1);
892
gchar* icon_name = g_strdup_printf ("%s_badge-symbolic", session_name);
893
g_free (session_name);
894
if (gtk_icon_theme_has_icon(icon_theme, icon_name))
895
gtk_image_set_from_icon_name (GTK_IMAGE(session_badge), icon_name, GTK_ICON_SIZE_MENU);
897
gtk_image_set_from_icon_name (GTK_IMAGE(session_badge), "document-properties-symbolic", GTK_ICON_SIZE_MENU);
903
menu_iter = menu_items;
906
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_iter->data), TRUE);
909
g_free (current_session);
910
current_session = g_strdup(session);
911
g_free (last_session);
917
GList *menu_items, *menu_iter;
919
/* if the user manually selected a language, use it */
920
if (current_language)
921
return g_strdup (current_language);
923
menu_items = gtk_container_get_children(GTK_CONTAINER(language_menu));
924
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
926
if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_iter->data)))
927
return g_strdup(g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
934
set_language (const gchar *language)
936
const gchar *default_language = NULL;
937
GList *menu_items, *menu_iter;
939
if (!gtk_widget_get_visible (language_menuitem))
941
g_free (current_language);
942
current_language = g_strdup (language);
946
menu_items = gtk_container_get_children(GTK_CONTAINER(language_menu));
950
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
954
s = g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE));
955
matched = g_strcmp0 (s, language) == 0;
959
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_iter->data), TRUE);
960
g_free (current_language);
961
current_language = g_strdup(language);
962
gtk_menu_item_set_label(GTK_MENU_ITEM(language_menuitem),language);
968
/* If failed to find this language, then try the default */
969
if (lightdm_get_language ())
971
default_language = lightdm_language_get_code (lightdm_get_language ());
972
gtk_menu_item_set_label(GTK_MENU_ITEM (language_menuitem), default_language);
974
if (default_language && g_strcmp0 (default_language, language) != 0)
975
set_language (default_language);
976
/* If all else fails, just use the first language from the menu */
979
for (menu_iter = menu_items; menu_iter != NULL; menu_iter = g_list_next(menu_iter))
981
if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_iter->data)))
983
gtk_menu_item_set_label (GTK_MENU_ITEM (language_menuitem), g_strdup (g_object_get_data (G_OBJECT (menu_iter->data), LANGUAGE_DATA_CODE)));
991
set_message_label (LightDMMessageType type, const gchar *text)
993
if (type == LIGHTDM_MESSAGE_TYPE_INFO)
994
gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_INFO);
996
gtk_info_bar_set_message_type (info_bar, GTK_MESSAGE_ERROR);
997
gtk_label_set_text (message_label, text);
998
gtk_widget_set_visible (GTK_WIDGET (info_bar), text && text[0]);
1549
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), label);
1552
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL, label, g_free);
1553
g_object_set_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP, GINT_TO_POINTER (i));
1555
g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
1556
gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
1557
gtk_widget_show (GTK_WIDGET (menuitem));
1560
g_object_unref (registry);
1561
g_object_unref (config_item);
1562
g_object_unref (config);
1564
GSList *menu_group = NULL;
1567
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
1568
(GDestroyNotify)gtk_widget_destroy);
1570
for (item = lightdm_get_layouts (); item; item = g_list_next (item))
1572
LightDMLayout *layout = item->data;
1573
GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
1574
menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
1576
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL,
1577
g_strdelimit (g_strdup (lightdm_layout_get_name (layout)), "\t ", '_'), g_free);
1578
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_NAME,
1579
g_strdup (lightdm_layout_get_name (layout)), g_free);
1581
g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
1582
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), lightdm_layout_get_description (layout));
1583
gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
1584
gtk_widget_show (GTK_WIDGET (menuitem));
1590
update_layouts_menu_state (void)
1592
#ifdef HAVE_LIBXKLAVIER
1593
XklState *state = xkl_engine_get_current_state (xkl_engine);
1594
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
1595
GtkCheckMenuItem *menu_item = g_list_nth_data (menu_items, state->group);
1599
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
1600
g_object_get_data (G_OBJECT (menu_item), LAYOUT_DATA_LABEL));
1601
gtk_check_menu_item_set_active (menu_item, TRUE);
1604
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem), "??");
1605
g_list_free (menu_items);
1607
LightDMLayout *layout = lightdm_get_layout ();
1608
g_return_if_fail (layout != NULL);
1610
const gchar *name = lightdm_layout_get_name (layout);
1611
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
1613
for (menu_iter = menu_items; menu_iter; menu_iter = g_list_next (menu_iter))
1615
if (g_strcmp0 (name, g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_NAME)) == 0)
1617
gtk_check_menu_item_set_active (menu_iter->data, TRUE);
1618
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
1619
g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_LABEL));
1623
g_list_free (menu_items);
1627
#ifdef HAVE_LIBXKLAVIER
1629
xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group,
1630
gboolean restore, gpointer user_data)
1632
if (change == GROUP_CHANGED)
1633
update_layouts_menu_state ();
1637
xkl_config_changed_cb (XklEngine *engine, gpointer user_data)
1639
/* tip: xkl_config_rec_get_from_server() return old settings */
1640
update_layouts_menu ();
1641
update_layouts_menu_state ();
1644
static GdkFilterReturn
1645
xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer data)
1647
XEvent *xevent = (XEvent *) xev;
1648
xkl_engine_filter_events (xkl_engine, xevent);
1649
return GDK_FILTER_CONTINUE;
1653
/* a11y indciator */
1656
a11y_font_cb (GtkCheckMenuItem *item)
1658
if (gtk_check_menu_item_get_active (item))
1660
gchar *font_name, **tokens;
1663
g_object_get (gtk_settings_get_default (), "gtk-font-name", &font_name, NULL);
1664
tokens = g_strsplit (font_name, " ", -1);
1665
length = g_strv_length (tokens);
1668
gint size = atoi (tokens[length - 1]);
1671
g_free (tokens[length - 1]);
1672
tokens[length - 1] = g_strdup_printf ("%d", size + 10);
1674
font_name = g_strjoinv (" ", tokens);
1677
g_strfreev (tokens);
1679
g_object_set (gtk_settings_get_default (), "gtk-font-name", font_name, NULL);
1683
g_object_set (gtk_settings_get_default (), "gtk-font-name", default_font_name, NULL);
1688
a11y_contrast_cb (GtkCheckMenuItem *item)
1690
if (gtk_check_menu_item_get_active (item))
1692
g_object_set (gtk_settings_get_default (), "gtk-theme-name", "HighContrast", NULL);
1693
g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", "HighContrast", NULL);
1697
g_object_set (gtk_settings_get_default (), "gtk-theme-name", default_theme_name, NULL);
1698
g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", default_icon_theme_name, NULL);
1703
a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data)
1705
if (gtk_check_menu_item_get_active (item))
1706
menu_command_run (a11y_keyboard_command);
1708
menu_command_stop (a11y_keyboard_command);
1712
a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data)
1714
if (gtk_check_menu_item_get_active (item))
1715
menu_command_run (a11y_reader_command);
1717
menu_command_stop (a11y_reader_command);
1720
/* Power indicator */
1723
power_menu_cb (GtkWidget *menuitem, gpointer userdata)
1725
gtk_widget_set_sensitive (suspend_menuitem, lightdm_get_can_suspend ());
1726
gtk_widget_set_sensitive (hibernate_menuitem, lightdm_get_can_hibernate ());
1727
gtk_widget_set_sensitive (restart_menuitem, lightdm_get_can_restart ());
1728
gtk_widget_set_sensitive (shutdown_menuitem, lightdm_get_can_shutdown ());
1732
suspend_cb (GtkWidget *widget, LightDMGreeter *greeter)
1734
lightdm_suspend (NULL);
1738
hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter)
1740
lightdm_hibernate (NULL);
1744
restart_cb (GtkWidget *widget, LightDMGreeter *greeter)
1746
if (show_power_prompt ("restart", "view-refresh-symbolic",
1748
_("Are you sure you want to close all programs and restart the computer?")))
1749
lightdm_restart (NULL);
1753
shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
1755
if (show_power_prompt ("shutdown", "system-shutdown-symbolic",
1757
_("Are you sure you want to close all programs and shut down the computer?")))
1758
lightdm_shutdown (NULL);
1455
2090
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1);
1457
set_displayed_user(greeter, user);
2092
set_displayed_user (greeter, user);
1461
2096
set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, NULL);
1465
get_message_label (void)
1467
return gtk_label_get_text (message_label);
1471
process_prompts (LightDMGreeter *greeter)
1473
if (!pending_questions)
1476
/* always allow the user to change username again */
1477
gtk_widget_set_sensitive (GTK_WIDGET (username_entry), TRUE);
1478
gtk_widget_set_sensitive (GTK_WIDGET (password_entry), TRUE);
1480
/* Special case: no user selected from list, so PAM asks us for the user
1481
* via a prompt. For that case, use the username field */
1482
if (!prompted && pending_questions && !pending_questions->next &&
1483
((PAMConversationMessage *) pending_questions->data)->is_prompt &&
1484
((PAMConversationMessage *) pending_questions->data)->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET &&
1485
gtk_widget_get_visible ((GTK_WIDGET (username_entry))) &&
1486
lightdm_greeter_get_authentication_user (greeter) == NULL)
1489
prompt_active = TRUE;
1490
gtk_widget_grab_focus (GTK_WIDGET (username_entry));
1491
gtk_widget_show (GTK_WIDGET (password_entry));
1495
while (pending_questions)
1497
PAMConversationMessage *message = (PAMConversationMessage *) pending_questions->data;
1498
pending_questions = g_slist_remove (pending_questions, (gconstpointer) message);
1500
if (!message->is_prompt)
1502
/* FIXME: this doesn't show multiple messages, but that was
1503
* already the case before. */
1504
set_message_label (message->type.message, message->text);
1508
gtk_widget_show (GTK_WIDGET (password_entry));
1509
gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1510
gtk_entry_set_text (password_entry, "");
1511
gtk_entry_set_visibility (password_entry, message->type.prompt != LIGHTDM_PROMPT_TYPE_SECRET);
1512
if (get_message_label()[0] == 0 && password_prompted)
1514
/* No message was provided beforehand and this is not the
1515
* first password prompt, so use the prompt as label,
1516
* otherwise the user will be completely unclear of what
1517
* is going on. Actually, the fact that prompt messages are
1518
* not shown is problematic in general, especially if
1519
* somebody uses a custom PAM module that wants to ask
1520
* something different. */
1521
gchar *str = message->text;
1522
if (g_str_has_suffix (str, ": "))
1523
str = g_strndup (str, strlen (str) - 2);
1524
else if (g_str_has_suffix (str, ":"))
1525
str = g_strndup (str, strlen (str) - 1);
1526
set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, str);
1527
if (str != message->text)
1530
gtk_widget_grab_focus (GTK_WIDGET (password_entry));
1532
password_prompted = TRUE;
1533
prompt_active = TRUE;
1535
/* If we have more stuff after a prompt, assume that other prompts are pending,
1541
2099
void login_cb (GtkWidget *widget);
1542
2100
G_MODULE_EXPORT
1679
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
1682
suspend_cb (GtkWidget *widget, LightDMGreeter *greeter)
1684
lightdm_suspend (NULL);
1687
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
1690
hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter)
1692
lightdm_hibernate (NULL);
1696
show_power_prompt (const gchar* action, const gchar* message, const gchar* icon,
1697
const gchar* dialog_name, const gchar* button_name)
1703
const GList *items, *item;
1704
gint logged_in_users = 0;
1707
/* Check if there are still users logged in, count them and if so, display a warning */
1708
items = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
1709
for (item = items; item; item = item->next)
1711
LightDMUser *user = item->data;
1712
if (lightdm_user_get_logged_in (user))
1715
if (logged_in_users > 0)
1717
if (logged_in_users > 1)
1718
warning = g_strdup_printf (_("Warning: There are still %d users logged in."), logged_in_users);
1720
warning = g_strdup_printf (_("Warning: There is still %d user logged in."), logged_in_users);
1721
message = g_markup_printf_escaped ("<b>%s</b>\n%s", warning, message);
1725
/* Prepare the dialog */
1726
dialog = gtk_message_dialog_new (NULL,
1731
gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", message);
1732
button = gtk_dialog_add_button(GTK_DIALOG (dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
1733
gtk_widget_set_name(button, "cancel_button");
1734
button = gtk_dialog_add_button(GTK_DIALOG (dialog), action, GTK_RESPONSE_OK);
1735
gtk_widget_set_name(button, button_name);
1738
image = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_DIALOG);
1739
gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(dialog), image);
1741
/* Make the dialog themeable and attractive */
1742
gtk_style_context_add_class (GTK_STYLE_CONTEXT (gtk_widget_get_style_context (GTK_WIDGET (dialog))), "lightdm-gtk-greeter");
1743
gtk_widget_set_name (dialog, dialog_name);
1744
gtk_container_set_border_width (GTK_CONTAINER (dialog), 18);
1746
greeter_background_add_subwindow (greeter_background, GTK_WINDOW (dialog));
1748
/* Hide the login window and show the dialog */
1749
gtk_widget_hide (GTK_WIDGET (login_window));
1750
gtk_widget_show_all (dialog);
1751
center_window (GTK_WINDOW (dialog), NULL, &WINDOW_POS_CENTER);
1753
result = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK;
1755
greeter_background_remove_subwindow(greeter_background, GTK_WINDOW (dialog));
1756
gtk_widget_destroy (dialog);
1757
gtk_widget_show (GTK_WIDGET (login_window));
1758
gtk_widget_queue_resize(GTK_WIDGET (login_window));
1763
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
1766
restart_cb (GtkWidget *widget, LightDMGreeter *greeter)
1768
if (show_power_prompt(_("Restart"), _("Are you sure you want to close all programs and restart the computer?"),
1769
"view-refresh-symbolic", "restart_dialog", "restart_button"))
1770
lightdm_restart (NULL);
1773
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
1776
shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
1778
if (show_power_prompt(_("Shut Down"), _("Are you sure you want to close all programs and shut down the computer?"),
1779
"system-shutdown-symbolic", "shutdown_dialog", "shutdown_button"))
1780
lightdm_shutdown (NULL);
1784
2238
user_added_cb (LightDMUserList *user_list, LightDMUser *user, LightDMGreeter *greeter)
2112
2444
return GDK_FILTER_CONTINUE;
2115
/* Layout functions and callbacks */
2118
layout_selected_cb(GtkCheckMenuItem *menuitem, gpointer user_data)
2120
if (gtk_check_menu_item_get_active (menuitem))
2122
#ifdef HAVE_LIBXKLAVIER
2123
gint group = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP));
2124
xkl_engine_lock_group (xkl_engine, group);
2126
const gchar *name = g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_NAME);
2128
for (item = lightdm_get_layouts (); item; item = g_list_next (item))
2130
if (g_strcmp0 (name, lightdm_layout_get_name (item->data)) == 0)
2132
lightdm_set_layout (item->data);
2133
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2134
g_object_get_data (G_OBJECT (menuitem), LAYOUT_DATA_LABEL));
2143
update_layouts_menu (void)
2145
#ifdef HAVE_LIBXKLAVIER
2146
XklConfigRegistry *registry;
2147
XklConfigRec *config;
2148
XklConfigItem *config_item;
2149
GSList *menu_group = NULL;
2152
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
2153
(GDestroyNotify)gtk_widget_destroy);
2155
config = xkl_config_rec_new ();
2156
if (!xkl_config_rec_get_from_server (config, xkl_engine))
2158
g_object_unref (config);
2159
g_warning ("Failed to get Xkl configuration from server");
2163
config_item = xkl_config_item_new ();
2164
registry = xkl_config_registry_get_instance (xkl_engine);
2165
xkl_config_registry_load (registry, FALSE);
2167
for (i = 0; config->layouts[i] != NULL; ++i)
2169
const gchar *layout = config->layouts[i] ? config->layouts[i] : "";
2170
const gchar *variant = config->variants[i] ? config->variants[i] : "";
2171
gchar *label = strlen (variant) > 0 ? g_strdup_printf ("%s_%s", layout, variant) : g_strdup (layout);
2173
GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
2174
menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
2176
g_snprintf (config_item->name, sizeof (config_item->name), "%s", variant);
2177
if (xkl_config_registry_find_variant (registry, layout, config_item))
2178
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
2181
g_snprintf (config_item->name, sizeof (config_item->name), "%s", layout);
2182
if (xkl_config_registry_find_layout (registry, config_item))
2183
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), config_item->description);
2185
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), label);
2188
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL, label, g_free);
2189
g_object_set_data (G_OBJECT (menuitem), LAYOUT_DATA_GROUP, GINT_TO_POINTER (i));
2191
g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
2192
gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
2193
gtk_widget_show (GTK_WIDGET (menuitem));
2196
g_object_unref (registry);
2197
g_object_unref (config_item);
2198
g_object_unref (config);
2200
GSList *menu_group = NULL;
2203
g_list_free_full (gtk_container_get_children (GTK_CONTAINER (layout_menu)),
2204
(GDestroyNotify)gtk_widget_destroy);
2206
for (item = lightdm_get_layouts (); item; item = g_list_next (item))
2208
LightDMLayout *layout = item->data;
2209
GtkWidget *menuitem = gtk_radio_menu_item_new (menu_group);
2210
menu_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
2212
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_LABEL,
2213
g_strdelimit (g_strdup (lightdm_layout_get_name (layout)), "\t ", '_'), g_free);
2214
g_object_set_data_full (G_OBJECT (menuitem), LAYOUT_DATA_NAME,
2215
g_strdup (lightdm_layout_get_name (layout)), g_free);
2217
g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (layout_selected_cb), NULL);
2218
gtk_menu_item_set_label (GTK_MENU_ITEM (menuitem), lightdm_layout_get_description (layout));
2219
gtk_menu_shell_append (GTK_MENU_SHELL (layout_menu), menuitem);
2220
gtk_widget_show (GTK_WIDGET (menuitem));
2226
update_layouts_menu_state (void)
2228
#ifdef HAVE_LIBXKLAVIER
2229
XklState *state = xkl_engine_get_current_state (xkl_engine);
2230
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
2231
GtkCheckMenuItem *menu_item = g_list_nth_data (menu_items, state->group);
2235
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2236
g_object_get_data (G_OBJECT (menu_item), LAYOUT_DATA_LABEL));
2237
gtk_check_menu_item_set_active(menu_item, TRUE);
2240
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem), "??");
2241
g_list_free (menu_items);
2243
LightDMLayout *layout = lightdm_get_layout ();
2244
g_return_if_fail (layout != NULL);
2246
const gchar *name = lightdm_layout_get_name (layout);
2247
GList *menu_items = gtk_container_get_children (GTK_CONTAINER (layout_menu));
2249
for (menu_iter = menu_items; menu_iter; menu_iter = g_list_next (menu_iter))
2251
if (g_strcmp0 (name, g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_NAME)) == 0)
2253
gtk_check_menu_item_set_active (menu_iter->data, TRUE);
2254
gtk_menu_item_set_label (GTK_MENU_ITEM (layout_menuitem),
2255
g_object_get_data (G_OBJECT (menu_iter->data), LAYOUT_DATA_LABEL));
2259
g_list_free (menu_items);
2263
#ifdef HAVE_LIBXKLAVIER
2265
xkl_state_changed_cb (XklEngine *engine, XklEngineStateChange change, gint group,
2266
gboolean restore, gpointer user_data)
2268
if (change == GROUP_CHANGED)
2269
update_layouts_menu_state ();
2273
xkl_config_changed_cb (XklEngine *engine, gpointer user_data)
2275
/* tip: xkl_config_rec_get_from_server() return old settings */
2276
update_layouts_menu ();
2277
update_layouts_menu_state ();
2280
static GdkFilterReturn
2281
xkl_xevent_filter (GdkXEvent *xev, GdkEvent *event, gpointer data)
2283
XEvent *xevent = (XEvent *) xev;
2284
xkl_engine_filter_events (xkl_engine, xevent);
2285
return GDK_FILTER_CONTINUE;
2290
2448
main (int argc, char **argv)