Merge lp:~kalgasnik/lightdm-gtk-greeter/post-2.0.0 into lp:~lightdm-gtk-greeter-team/lightdm-gtk-greeter/trunk
- post-2.0.0
- Merge into trunk
Status: | Merged | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 326 | ||||||||||||||||
Proposed branch: | lp:~kalgasnik/lightdm-gtk-greeter/post-2.0.0 | ||||||||||||||||
Merge into: | lp:~lightdm-gtk-greeter-team/lightdm-gtk-greeter/trunk | ||||||||||||||||
Diff against target: |
1539 lines (+685/-278) 8 files modified
src/Makefile.am (+2/-0) src/greeterbackground.c (+75/-39) src/greeterbackground.h (+16/-3) src/greeterconfiguration.c (+371/-0) src/greeterconfiguration.h (+57/-0) src/lightdm-gtk-greeter-fallback.css (+5/-5) src/lightdm-gtk-greeter.c (+154/-229) src/lightdm-gtk-greeter.glade (+5/-2) |
||||||||||||||||
To merge this branch: | bzr merge lp:~kalgasnik/lightdm-gtk-greeter/post-2.0.0 | ||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sean Davis | Approve | ||
Andrew P. | Pending | ||
Review via email:
|
Commit message
Description of the change
1. Greeter can go to infinite loop at launch when used with two monitors in mirrored mode and active-
http://
http://
http://
https:/
2. gtk_widget_reparent marked as deprecated in 3.14 but gtk_container_
gtk_widget_reparent used in greeter to move screen_overlay from on monitor window to another.
Looks like remove/add leaves GtkPlug in invalid state.
http://
http://
3. Sending "WM_TAKE_FOCUS" to active monitor window, "onboard" just doesn't work in xembed mode without it.
4. Greeter doesn't lose focus when monitors configuration changed.
5. Multiple configuration files. Order:
g_get_system_
.../lightdm/
.../lightdm/
g_get_system_
.../lightdm/
.../lightdm/
/etc/lightdm/
/etc/lightdm/
Sample:
/usr/share/
/etc/xdg/
/etc/xdg/
/etc/xdg/
/etc/lightdm/
/etc/lightdm/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Simon Steinbeiß (ochosi) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sean Davis (bluesabre) wrote : | # |
Simon,
Actually, other than the configuration location (not really a "feature"), I'd say these are all bug fixes.
#1 is a critical bug that can leave the greeter completely non-functional.
#2 and #3 break accessibility by making the on-screen keyboard unusable.
#4 means that keyboard input would be lost without using a mouse.
I haven't tested the branch yet, but these all sound reasonable to me. I'll test it out this weekend.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sean Davis (bluesabre) wrote : | # |
I just tested this branch with a second monitor. It seems the white screen bug is still present.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Andrew P. (kalgasnik) wrote : | # |
Log with allow-debugging
Is it white "need to click or use active-monitor=0" screen?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Sean Davis (bluesabre) wrote : | # |
I think I had some other components interfering. This time I built a proper package and installed it over a clean system, and everything seems to be okay. Going to merge this one in.
Preview Diff
1 | === modified file 'src/Makefile.am' | |||
2 | --- src/Makefile.am 2014-11-04 11:38:36 +0000 | |||
3 | +++ src/Makefile.am 2015-03-29 05:44:39 +0000 | |||
4 | @@ -10,6 +10,8 @@ | |||
5 | 10 | lightdm-gtk-greeter.c \ | 10 | lightdm-gtk-greeter.c \ |
6 | 11 | greeterbackground.c \ | 11 | greeterbackground.c \ |
7 | 12 | greeterbackground.h \ | 12 | greeterbackground.h \ |
8 | 13 | greeterconfiguration.c \ | ||
9 | 14 | greeterconfiguration.h \ | ||
10 | 13 | greetermenubar.c \ | 15 | greetermenubar.c \ |
11 | 14 | greetermenubar.h | 16 | greetermenubar.h |
12 | 15 | 17 | ||
13 | 16 | 18 | ||
14 | === modified file 'src/greeterbackground.c' | |||
15 | --- src/greeterbackground.c 2014-12-10 07:59:02 +0000 | |||
16 | +++ src/greeterbackground.c 2015-03-29 05:44:39 +0000 | |||
17 | @@ -58,7 +58,7 @@ | |||
18 | 58 | } BackgroundConfig; | 58 | } BackgroundConfig; |
19 | 59 | 59 | ||
20 | 60 | /* Transition configuration | 60 | /* Transition configuration |
22 | 61 | Used to as part of <MonitorConfig> and <Monitor> */ | 61 | Used as part of <MonitorConfig> and <Monitor> */ |
23 | 62 | typedef struct | 62 | typedef struct |
24 | 63 | { | 63 | { |
25 | 64 | /* Transition duration, in ms */ | 64 | /* Transition duration, in ms */ |
26 | @@ -177,9 +177,6 @@ | |||
27 | 177 | gboolean follow_cursor; | 177 | gboolean follow_cursor; |
28 | 178 | /* Use cursor position to determinate initial active monitor */ | 178 | /* Use cursor position to determinate initial active monitor */ |
29 | 179 | gboolean follow_cursor_to_init; | 179 | gboolean follow_cursor_to_init; |
30 | 180 | |||
31 | 181 | /* Name => transition function, inited in set_monitor_config() */ | ||
32 | 182 | GHashTable* transition_types; | ||
33 | 183 | }; | 180 | }; |
34 | 184 | 181 | ||
35 | 185 | enum | 182 | enum |
36 | @@ -205,10 +202,10 @@ | |||
37 | 205 | void greeter_background_set_monitor_config (GreeterBackground* background, | 202 | void greeter_background_set_monitor_config (GreeterBackground* background, |
38 | 206 | const gchar* name, | 203 | const gchar* name, |
39 | 207 | const gchar* bg, /* NULL to use fallback value */ | 204 | const gchar* bg, /* NULL to use fallback value */ |
42 | 208 | gboolean user_bg, gboolean user_bg_used, | 205 | gint user_bg, /* -1 to use fallback value */ |
43 | 209 | gboolean laptop, gboolean laptop_used, | 206 | gint laptop, /* -1 to use fallback value */ |
44 | 210 | gint transition_duration, /* -1 to use fallback value */ | 207 | gint transition_duration, /* -1 to use fallback value */ |
46 | 211 | const gchar* transition_type); /* NULL to use fallback value */ | 208 | TransitionType transition_type); /* NULL to use fallback value */ |
47 | 212 | void greeter_background_remove_monitor_config (GreeterBackground* background, | 209 | void greeter_background_remove_monitor_config (GreeterBackground* background, |
48 | 213 | const gchar* name); | 210 | const gchar* name); |
49 | 214 | gchar** greeter_background_get_configured_monitors (GreeterBackground* background); | 211 | gchar** greeter_background_get_configured_monitors (GreeterBackground* background); |
50 | @@ -296,7 +293,7 @@ | |||
51 | 296 | static void set_surface_as_root (GdkScreen* screen, | 293 | static void set_surface_as_root (GdkScreen* screen, |
52 | 297 | cairo_surface_t* surface); | 294 | cairo_surface_t* surface); |
53 | 298 | static gdouble transition_func_linear (gdouble x); | 295 | static gdouble transition_func_linear (gdouble x); |
55 | 299 | static gdouble transition_func_easy_in_out (gdouble x); | 296 | static gdouble transition_func_ease_in_out (gdouble x); |
56 | 300 | 297 | ||
57 | 301 | /* Implemented in lightdm-gtk-greeter.c */ | 298 | /* Implemented in lightdm-gtk-greeter.c */ |
58 | 302 | gpointer greeter_save_focus(GtkWidget* widget); | 299 | gpointer greeter_save_focus(GtkWidget* widget); |
59 | @@ -317,7 +314,7 @@ | |||
60 | 317 | .transition = | 314 | .transition = |
61 | 318 | { | 315 | { |
62 | 319 | .duration = 500, | 316 | .duration = 500, |
64 | 320 | .func = transition_func_easy_in_out, | 317 | .func = transition_func_ease_in_out, |
65 | 321 | .draw = (TransitionDraw)monitor_transition_draw_alpha | 318 | .draw = (TransitionDraw)monitor_transition_draw_alpha |
66 | 322 | } | 319 | } |
67 | 323 | }; | 320 | }; |
68 | @@ -413,10 +410,10 @@ | |||
69 | 413 | greeter_background_set_monitor_config(GreeterBackground* background, | 410 | greeter_background_set_monitor_config(GreeterBackground* background, |
70 | 414 | const gchar* name, | 411 | const gchar* name, |
71 | 415 | const gchar* bg, | 412 | const gchar* bg, |
74 | 416 | gboolean user_bg, gboolean user_bg_used, | 413 | gint user_bg, |
75 | 417 | gboolean laptop, gboolean laptop_used, | 414 | gint laptop, |
76 | 418 | gint transition_duration, | 415 | gint transition_duration, |
78 | 419 | const gchar* transition_type) | 416 | TransitionType transition_type) |
79 | 420 | { | 417 | { |
80 | 421 | g_return_if_fail(GREETER_IS_BACKGROUND(background)); | 418 | g_return_if_fail(GREETER_IS_BACKGROUND(background)); |
81 | 422 | GreeterBackgroundPrivate* priv = background->priv; | 419 | GreeterBackgroundPrivate* priv = background->priv; |
82 | @@ -427,29 +424,22 @@ | |||
83 | 427 | 424 | ||
84 | 428 | if(!background_config_initialize(&config->bg, bg)) | 425 | if(!background_config_initialize(&config->bg, bg)) |
85 | 429 | background_config_copy(&FALLBACK->bg, &config->bg); | 426 | background_config_copy(&FALLBACK->bg, &config->bg); |
88 | 430 | config->user_bg = user_bg_used ? user_bg : FALLBACK->user_bg; | 427 | config->user_bg = user_bg >= 0 ? user_bg : FALLBACK->user_bg; |
89 | 431 | config->laptop = laptop_used ? laptop : FALLBACK->laptop; | 428 | config->laptop = laptop >= 0 ? laptop : FALLBACK->laptop; |
90 | 432 | config->transition.duration = transition_duration >= 0 ? transition_duration : FALLBACK->transition.duration; | 429 | config->transition.duration = transition_duration >= 0 ? transition_duration : FALLBACK->transition.duration; |
91 | 433 | config->transition.draw = FALLBACK->transition.draw; | 430 | config->transition.draw = FALLBACK->transition.draw; |
92 | 434 | 431 | ||
94 | 435 | if(transition_type) | 432 | switch(transition_type) |
95 | 436 | { | 433 | { |
107 | 437 | if(!priv->transition_types) | 434 | case TRANSITION_TYPE_NONE: |
108 | 438 | { | 435 | config->transition.func = NULL; break; |
109 | 439 | priv->transition_types = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); | 436 | case TRANSITION_TYPE_LINEAR: |
110 | 440 | g_hash_table_insert(priv->transition_types, g_strdup("none"), NULL); | 437 | config->transition.func = transition_func_linear; break; |
111 | 441 | g_hash_table_insert(priv->transition_types, g_strdup("linear"), transition_func_linear); | 438 | case TRANSITION_TYPE_EASE_IN_OUT: |
112 | 442 | g_hash_table_insert(priv->transition_types, g_strdup("easy-in-out"), transition_func_easy_in_out); | 439 | config->transition.func = transition_func_ease_in_out; break; |
113 | 443 | } | 440 | default: |
103 | 444 | if(!g_hash_table_lookup_extended(priv->transition_types, transition_type, NULL, (gpointer*)&config->transition.func)) | ||
104 | 445 | { | ||
105 | 446 | g_warning("[Background] Invalid transition type for '%s' monitor: '%s'. Using fallback value.", | ||
106 | 447 | name, transition_type); | ||
114 | 448 | config->transition.func = FALLBACK->transition.func; | 441 | config->transition.func = FALLBACK->transition.func; |
115 | 449 | } | ||
116 | 450 | } | 442 | } |
117 | 451 | else | ||
118 | 452 | config->transition.func = FALLBACK->transition.func; | ||
119 | 453 | 443 | ||
120 | 454 | if(FALLBACK == priv->default_config) | 444 | if(FALLBACK == priv->default_config) |
121 | 455 | g_hash_table_insert(priv->configs, g_strdup(name), config); | 445 | g_hash_table_insert(priv->configs, g_strdup(name), config); |
122 | @@ -495,12 +485,18 @@ | |||
123 | 495 | g_return_if_fail(GREETER_IS_BACKGROUND(background)); | 485 | g_return_if_fail(GREETER_IS_BACKGROUND(background)); |
124 | 496 | g_return_if_fail(GDK_IS_SCREEN(screen)); | 486 | g_return_if_fail(GDK_IS_SCREEN(screen)); |
125 | 497 | 487 | ||
127 | 498 | g_debug("[Background] Connecting to screen: %p", screen); | 488 | g_debug("[Background] Connecting to screen: %p (%dx%dpx, %dx%dmm)", screen, |
128 | 489 | gdk_screen_get_width(screen), gdk_screen_get_height(screen), | ||
129 | 490 | gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm(screen)); | ||
130 | 499 | 491 | ||
131 | 500 | GreeterBackgroundPrivate* priv = background->priv; | 492 | GreeterBackgroundPrivate* priv = background->priv; |
133 | 501 | 493 | gpointer saved_focus = NULL; | |
134 | 502 | if(priv->screen) | 494 | if(priv->screen) |
135 | 495 | { | ||
136 | 496 | if (priv->active_monitor) | ||
137 | 497 | saved_focus = greeter_save_focus(priv->child); | ||
138 | 503 | greeter_background_disconnect(background); | 498 | greeter_background_disconnect(background); |
139 | 499 | } | ||
140 | 504 | 500 | ||
141 | 505 | priv->screen = screen; | 501 | priv->screen = screen; |
142 | 506 | priv->monitors_size = gdk_screen_get_n_monitors(screen); | 502 | priv->monitors_size = gdk_screen_get_n_monitors(screen); |
143 | @@ -513,7 +509,9 @@ | |||
144 | 513 | Monitor* first_not_skipped_monitor = NULL; | 509 | Monitor* first_not_skipped_monitor = NULL; |
145 | 514 | 510 | ||
146 | 515 | GHashTable* images_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); | 511 | GHashTable* images_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); |
147 | 512 | cairo_region_t *screen_region = cairo_region_create(); | ||
148 | 516 | gint i; | 513 | gint i; |
149 | 514 | |||
150 | 517 | for(i = 0; i < priv->monitors_size; ++i) | 515 | for(i = 0; i < priv->monitors_size; ++i) |
151 | 518 | { | 516 | { |
152 | 519 | const MonitorConfig* config; | 517 | const MonitorConfig* config; |
153 | @@ -553,6 +551,15 @@ | |||
154 | 553 | config = &DEFAULT_MONITOR_CONFIG; | 551 | config = &DEFAULT_MONITOR_CONFIG; |
155 | 554 | } | 552 | } |
156 | 555 | 553 | ||
157 | 554 | /* Simple check to skip fully overlapped monitors. | ||
158 | 555 | Actually, it's can track only monitors in "mirrors" mode. Nothing more. */ | ||
159 | 556 | if(cairo_region_contains_rectangle(screen_region, &monitor->geometry) == CAIRO_REGION_OVERLAP_IN) | ||
160 | 557 | { | ||
161 | 558 | g_debug("[Background] Skipping monitor %s #%d, its area is already used by other monitors", printable_name, i); | ||
162 | 559 | continue; | ||
163 | 560 | } | ||
164 | 561 | cairo_region_union_rectangle(screen_region, &monitor->geometry); | ||
165 | 562 | |||
166 | 556 | if(!first_not_skipped_monitor) | 563 | if(!first_not_skipped_monitor) |
167 | 557 | first_not_skipped_monitor = monitor; | 564 | first_not_skipped_monitor = monitor; |
168 | 558 | 565 | ||
169 | @@ -578,9 +585,8 @@ | |||
170 | 578 | for(item = priv->accel_groups; item != NULL; item = g_slist_next(item)) | 585 | for(item = priv->accel_groups; item != NULL; item = g_slist_next(item)) |
171 | 579 | gtk_window_add_accel_group(monitor->window, item->data); | 586 | gtk_window_add_accel_group(monitor->window, item->data); |
172 | 580 | 587 | ||
176 | 581 | if(priv->follow_cursor) | 588 | g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event", |
177 | 582 | g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event", | 589 | G_CALLBACK(monitor_window_enter_notify_cb), monitor); |
175 | 583 | G_CALLBACK(monitor_window_enter_notify_cb), monitor); | ||
178 | 584 | 590 | ||
179 | 585 | if(config->user_bg) | 591 | if(config->user_bg) |
180 | 586 | priv->customized_monitors = g_slist_prepend(priv->customized_monitors, monitor); | 592 | priv->customized_monitors = g_slist_prepend(priv->customized_monitors, monitor); |
181 | @@ -624,9 +630,16 @@ | |||
182 | 624 | } | 630 | } |
183 | 625 | } | 631 | } |
184 | 626 | } | 632 | } |
185 | 633 | |||
186 | 627 | if(!priv->active_monitor) | 634 | if(!priv->active_monitor) |
187 | 628 | greeter_background_set_active_monitor(background, NULL); | 635 | greeter_background_set_active_monitor(background, NULL); |
188 | 629 | 636 | ||
189 | 637 | if(saved_focus) | ||
190 | 638 | { | ||
191 | 639 | greeter_restore_focus(saved_focus); | ||
192 | 640 | g_free(saved_focus); | ||
193 | 641 | } | ||
194 | 642 | |||
195 | 630 | priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed", | 643 | priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed", |
196 | 631 | G_CALLBACK(greeter_background_monitors_changed_cb), | 644 | G_CALLBACK(greeter_background_monitors_changed_cb), |
197 | 632 | background); | 645 | background); |
198 | @@ -768,8 +781,9 @@ | |||
199 | 768 | gpointer focus = greeter_save_focus(priv->child); | 781 | gpointer focus = greeter_save_focus(priv->child); |
200 | 769 | 782 | ||
201 | 770 | if(old_parent) | 783 | if(old_parent) |
204 | 771 | gtk_container_remove(GTK_CONTAINER(old_parent), priv->child); | 784 | gtk_widget_reparent(priv->child, GTK_WIDGET(active->window)); |
205 | 772 | gtk_container_add(GTK_CONTAINER(active->window), priv->child); | 785 | else |
206 | 786 | gtk_container_add(GTK_CONTAINER(active->window), priv->child); | ||
207 | 773 | 787 | ||
208 | 774 | gtk_window_present(active->window); | 788 | gtk_window_present(active->window); |
209 | 775 | greeter_restore_focus(focus); | 789 | greeter_restore_focus(focus); |
210 | @@ -1393,8 +1407,30 @@ | |||
211 | 1393 | GdkEventCrossing* event, | 1407 | GdkEventCrossing* event, |
212 | 1394 | const Monitor* monitor) | 1408 | const Monitor* monitor) |
213 | 1395 | { | 1409 | { |
216 | 1396 | if(monitor->object->priv->active_monitor != monitor && | 1410 | if(monitor->object->priv->active_monitor == monitor) |
217 | 1397 | greeter_background_monitor_enabled(monitor->object, monitor)) | 1411 | { |
218 | 1412 | GdkWindow *gdkwindow = gtk_widget_get_window (widget); | ||
219 | 1413 | Window window = GDK_WINDOW_XID (gdkwindow); | ||
220 | 1414 | Display *display = GDK_WINDOW_XDISPLAY (gdkwindow); | ||
221 | 1415 | |||
222 | 1416 | static Atom wm_protocols = None; | ||
223 | 1417 | static Atom wm_take_focus = None; | ||
224 | 1418 | |||
225 | 1419 | if (!wm_protocols) | ||
226 | 1420 | wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); | ||
227 | 1421 | if (!wm_take_focus) | ||
228 | 1422 | wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False); | ||
229 | 1423 | |||
230 | 1424 | XEvent ev = {0}; | ||
231 | 1425 | ev.xclient.type = ClientMessage; | ||
232 | 1426 | ev.xclient.window = window; | ||
233 | 1427 | ev.xclient.message_type = wm_protocols; | ||
234 | 1428 | ev.xclient.format = 32; | ||
235 | 1429 | ev.xclient.data.l[0] = wm_take_focus; | ||
236 | 1430 | ev.xclient.data.l[1] = CurrentTime; | ||
237 | 1431 | XSendEvent(display, window, False, 0L, &ev); | ||
238 | 1432 | } | ||
239 | 1433 | else if(monitor->object->priv->follow_cursor && greeter_background_monitor_enabled(monitor->object, monitor)) | ||
240 | 1398 | greeter_background_set_active_monitor(monitor->object, monitor); | 1434 | greeter_background_set_active_monitor(monitor->object, monitor); |
241 | 1399 | return FALSE; | 1435 | return FALSE; |
242 | 1400 | } | 1436 | } |
243 | @@ -1633,7 +1669,7 @@ | |||
244 | 1633 | } | 1669 | } |
245 | 1634 | 1670 | ||
246 | 1635 | static gdouble | 1671 | static gdouble |
248 | 1636 | transition_func_easy_in_out(gdouble x) | 1672 | transition_func_ease_in_out(gdouble x) |
249 | 1637 | { | 1673 | { |
250 | 1638 | return (1 - cos(M_PI*x))/2; | 1674 | return (1 - cos(M_PI*x))/2; |
251 | 1639 | } | 1675 | } |
252 | 1640 | 1676 | ||
253 | === modified file 'src/greeterbackground.h' | |||
254 | --- src/greeterbackground.h 2014-11-03 10:39:58 +0000 | |||
255 | +++ src/greeterbackground.h 2015-03-29 05:44:39 +0000 | |||
256 | @@ -14,6 +14,19 @@ | |||
257 | 14 | 14 | ||
258 | 15 | #define GREETER_BACKGROUND_DEFAULT "*" | 15 | #define GREETER_BACKGROUND_DEFAULT "*" |
259 | 16 | 16 | ||
260 | 17 | typedef enum | ||
261 | 18 | { | ||
262 | 19 | TRANSITION_TYPE_NONE, | ||
263 | 20 | TRANSITION_TYPE_EASE_IN_OUT, | ||
264 | 21 | TRANSITION_TYPE_LINEAR, | ||
265 | 22 | TRANSITION_TYPE_FALLBACK | ||
266 | 23 | } TransitionType; | ||
267 | 24 | |||
268 | 25 | typedef enum | ||
269 | 26 | { | ||
270 | 27 | TRANSITION_EFFECT_NONE, | ||
271 | 28 | } TransitionEffect; | ||
272 | 29 | |||
273 | 17 | typedef struct _GreeterBackground GreeterBackground; | 30 | typedef struct _GreeterBackground GreeterBackground; |
274 | 18 | typedef struct _GreeterBackgroundClass GreeterBackgroundClass; | 31 | typedef struct _GreeterBackgroundClass GreeterBackgroundClass; |
275 | 19 | 32 | ||
276 | @@ -25,10 +38,10 @@ | |||
277 | 25 | void greeter_background_set_monitor_config (GreeterBackground* background, | 38 | void greeter_background_set_monitor_config (GreeterBackground* background, |
278 | 26 | const gchar* name, | 39 | const gchar* name, |
279 | 27 | const gchar* bg, | 40 | const gchar* bg, |
282 | 28 | gboolean user_bg, gboolean user_bg_used, | 41 | gint user_bg, |
283 | 29 | gboolean laptop, gboolean laptop_used, | 42 | gint laptop, |
284 | 30 | gint transition_duration, | 43 | gint transition_duration, |
286 | 31 | const gchar* transition_func); | 44 | TransitionType transition_type); |
287 | 32 | void greeter_background_remove_monitor_config (GreeterBackground* background, | 45 | void greeter_background_remove_monitor_config (GreeterBackground* background, |
288 | 33 | const gchar* name); | 46 | const gchar* name); |
289 | 34 | gchar** greeter_background_get_configured_monitors (GreeterBackground* background); | 47 | gchar** greeter_background_get_configured_monitors (GreeterBackground* background); |
290 | 35 | 48 | ||
291 | === added file 'src/greeterconfiguration.c' | |||
292 | --- src/greeterconfiguration.c 1970-01-01 00:00:00 +0000 | |||
293 | +++ src/greeterconfiguration.c 2015-03-29 05:44:39 +0000 | |||
294 | @@ -0,0 +1,371 @@ | |||
295 | 1 | |||
296 | 2 | #include <glib.h> | ||
297 | 3 | |||
298 | 4 | #include "greeterconfiguration.h" | ||
299 | 5 | |||
300 | 6 | |||
301 | 7 | static GKeyFile* greeter_config = NULL; | ||
302 | 8 | static GKeyFile* state_config = NULL; | ||
303 | 9 | static gchar* state_filename = NULL; | ||
304 | 10 | |||
305 | 11 | static GKeyFile* get_file_for_group (const gchar** group); | ||
306 | 12 | static void save_key_file (GKeyFile* config, const gchar* path); | ||
307 | 13 | static gboolean get_int (GKeyFile* config, const gchar* group, const gchar* key, gint* out); | ||
308 | 14 | static gboolean get_bool (GKeyFile* config, const gchar* group, const gchar* key, gboolean* out); | ||
309 | 15 | |||
310 | 16 | /* Implementation */ | ||
311 | 17 | |||
312 | 18 | static GList* | ||
313 | 19 | append_directory_content(GList* files, const gchar* path) | ||
314 | 20 | { | ||
315 | 21 | GError* error = NULL; | ||
316 | 22 | gchar* full_path = g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf.d", NULL); | ||
317 | 23 | GDir* dir = g_dir_open(full_path, 0, &error); | ||
318 | 24 | if(error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | ||
319 | 25 | g_warning("[Configuration] Failed to read configuration directory '%s': %s", full_path, error->message); | ||
320 | 26 | g_clear_error(&error); | ||
321 | 27 | |||
322 | 28 | GList* content = NULL; | ||
323 | 29 | if(dir) | ||
324 | 30 | { | ||
325 | 31 | const gchar *name; | ||
326 | 32 | while((name = g_dir_read_name(dir))) | ||
327 | 33 | { | ||
328 | 34 | if(!g_str_has_suffix(name, ".conf")) | ||
329 | 35 | continue; | ||
330 | 36 | content = g_list_prepend(content, g_build_filename(full_path, name, NULL)); | ||
331 | 37 | } | ||
332 | 38 | g_dir_close(dir); | ||
333 | 39 | |||
334 | 40 | if(content) | ||
335 | 41 | content = g_list_sort(content, (GCompareFunc)g_strcmp0); | ||
336 | 42 | } | ||
337 | 43 | |||
338 | 44 | content = g_list_append(content, g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf", NULL)); | ||
339 | 45 | |||
340 | 46 | GList* list_iter; | ||
341 | 47 | for(list_iter = content; list_iter; list_iter = g_list_next(list_iter)) | ||
342 | 48 | { | ||
343 | 49 | if(g_file_test(list_iter->data, G_FILE_TEST_IS_REGULAR)) | ||
344 | 50 | files = g_list_prepend(files, list_iter->data); | ||
345 | 51 | else | ||
346 | 52 | g_free(list_iter->data); | ||
347 | 53 | } | ||
348 | 54 | |||
349 | 55 | g_list_free(content); | ||
350 | 56 | g_free(full_path); | ||
351 | 57 | return files; | ||
352 | 58 | } | ||
353 | 59 | |||
354 | 60 | void | ||
355 | 61 | config_init(void) | ||
356 | 62 | { | ||
357 | 63 | GError* error = NULL; | ||
358 | 64 | |||
359 | 65 | gchar* state_config_dir = g_build_filename(g_get_user_cache_dir(), "lightdm-gtk-greeter", NULL); | ||
360 | 66 | state_filename = g_build_filename(state_config_dir, "state", NULL); | ||
361 | 67 | g_mkdir_with_parents(state_config_dir, 0775); | ||
362 | 68 | g_free(state_config_dir); | ||
363 | 69 | |||
364 | 70 | state_config = g_key_file_new(); | ||
365 | 71 | g_key_file_load_from_file(state_config, state_filename, G_KEY_FILE_NONE, &error); | ||
366 | 72 | if (error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | ||
367 | 73 | g_warning("[Configuration] Failed to load state from %s: %s", state_filename, error->message); | ||
368 | 74 | g_clear_error(&error); | ||
369 | 75 | |||
370 | 76 | |||
371 | 77 | gint i; | ||
372 | 78 | GList* files = NULL; | ||
373 | 79 | |||
374 | 80 | const gchar* const* dirs = g_get_system_data_dirs(); | ||
375 | 81 | for(i = 0; dirs[i]; ++i) | ||
376 | 82 | files = append_directory_content(files, dirs[i]); | ||
377 | 83 | |||
378 | 84 | dirs = g_get_system_config_dirs(); | ||
379 | 85 | for(i = 0; dirs[i]; ++i) | ||
380 | 86 | files = append_directory_content(files, dirs[i]); | ||
381 | 87 | |||
382 | 88 | gchar* config_path_tmp = g_path_get_dirname(CONFIG_FILE); | ||
383 | 89 | gchar* config_path = g_path_get_dirname(config_path_tmp); | ||
384 | 90 | files = append_directory_content(files, config_path); | ||
385 | 91 | g_free(config_path_tmp); | ||
386 | 92 | g_free(config_path); | ||
387 | 93 | |||
388 | 94 | files = g_list_reverse(files); | ||
389 | 95 | |||
390 | 96 | GKeyFile* tmp_config = NULL; | ||
391 | 97 | GList* file_iter = NULL; | ||
392 | 98 | for(file_iter = files; file_iter; file_iter = g_list_next(file_iter)) | ||
393 | 99 | { | ||
394 | 100 | const gchar* path = file_iter->data; | ||
395 | 101 | |||
396 | 102 | if(!tmp_config) | ||
397 | 103 | tmp_config = g_key_file_new(); | ||
398 | 104 | |||
399 | 105 | if(!g_key_file_load_from_file(tmp_config, path, G_KEY_FILE_NONE, &error)) | ||
400 | 106 | { | ||
401 | 107 | if(error) | ||
402 | 108 | { | ||
403 | 109 | g_warning("[Configuration] Failed to read file '%s': %s", path, error->message); | ||
404 | 110 | g_clear_error(&error); | ||
405 | 111 | } | ||
406 | 112 | else | ||
407 | 113 | g_warning("[Configuration] Failed to read file '%s'", path); | ||
408 | 114 | continue; | ||
409 | 115 | } | ||
410 | 116 | g_message("[Configuration] Reading file: %s", path); | ||
411 | 117 | |||
412 | 118 | if(!greeter_config) | ||
413 | 119 | { | ||
414 | 120 | greeter_config = tmp_config; | ||
415 | 121 | tmp_config = NULL; | ||
416 | 122 | continue; | ||
417 | 123 | } | ||
418 | 124 | |||
419 | 125 | gchar** group_iter = NULL; | ||
420 | 126 | gchar** groups = g_key_file_get_groups(tmp_config, NULL); | ||
421 | 127 | for(group_iter = groups; *group_iter; ++group_iter) | ||
422 | 128 | { | ||
423 | 129 | if(**group_iter == '-') | ||
424 | 130 | { | ||
425 | 131 | g_key_file_remove_group(greeter_config, *group_iter + 1, NULL); | ||
426 | 132 | continue; | ||
427 | 133 | } | ||
428 | 134 | |||
429 | 135 | gchar** key_iter = NULL; | ||
430 | 136 | gchar** keys = g_key_file_get_keys(tmp_config, *group_iter, NULL, NULL); | ||
431 | 137 | for(key_iter = keys; *key_iter; ++key_iter) | ||
432 | 138 | { | ||
433 | 139 | if(**key_iter == '-') | ||
434 | 140 | { | ||
435 | 141 | g_key_file_remove_key(greeter_config, *group_iter, *key_iter + 1, NULL); | ||
436 | 142 | continue; | ||
437 | 143 | } | ||
438 | 144 | |||
439 | 145 | gchar* value = g_key_file_get_value(tmp_config, *group_iter, *key_iter, NULL); | ||
440 | 146 | if(value) | ||
441 | 147 | { | ||
442 | 148 | g_key_file_set_value(greeter_config, *group_iter, *key_iter, value); | ||
443 | 149 | g_free(value); | ||
444 | 150 | } | ||
445 | 151 | } | ||
446 | 152 | g_strfreev(keys); | ||
447 | 153 | } | ||
448 | 154 | g_strfreev(groups); | ||
449 | 155 | } | ||
450 | 156 | if (tmp_config) | ||
451 | 157 | g_key_file_unref(tmp_config); | ||
452 | 158 | g_list_free_full(files, g_free); | ||
453 | 159 | |||
454 | 160 | if(!greeter_config) | ||
455 | 161 | greeter_config = g_key_file_new(); | ||
456 | 162 | } | ||
457 | 163 | |||
458 | 164 | static GKeyFile* | ||
459 | 165 | get_file_for_group(const gchar** group) | ||
460 | 166 | { | ||
461 | 167 | if(!*group) | ||
462 | 168 | *group = CONFIG_GROUP_DEFAULT; | ||
463 | 169 | |||
464 | 170 | if(*group[0] == '/') | ||
465 | 171 | { | ||
466 | 172 | (*group)++; | ||
467 | 173 | return state_config; | ||
468 | 174 | } | ||
469 | 175 | |||
470 | 176 | return greeter_config; | ||
471 | 177 | } | ||
472 | 178 | |||
473 | 179 | static void | ||
474 | 180 | save_key_file(GKeyFile* config, const gchar* path) | ||
475 | 181 | { | ||
476 | 182 | GError* error = NULL; | ||
477 | 183 | gsize data_length = 0; | ||
478 | 184 | gchar* data = g_key_file_to_data(config, &data_length, &error); | ||
479 | 185 | |||
480 | 186 | if(error) | ||
481 | 187 | { | ||
482 | 188 | g_warning("[Configuration] Failed to save file: %s", error->message); | ||
483 | 189 | g_clear_error(&error); | ||
484 | 190 | } | ||
485 | 191 | |||
486 | 192 | if(data) | ||
487 | 193 | { | ||
488 | 194 | g_file_set_contents(path, data, data_length, &error); | ||
489 | 195 | if(error) | ||
490 | 196 | { | ||
491 | 197 | g_warning("[Configuration] Failed to save file: %s", error->message); | ||
492 | 198 | g_clear_error(&error); | ||
493 | 199 | } | ||
494 | 200 | g_free(data); | ||
495 | 201 | } | ||
496 | 202 | } | ||
497 | 203 | |||
498 | 204 | static gboolean | ||
499 | 205 | get_int(GKeyFile* config, const gchar* group, const gchar* key, gint* out) | ||
500 | 206 | { | ||
501 | 207 | GError* error = NULL; | ||
502 | 208 | *out = g_key_file_get_integer(config, group, key, &error); | ||
503 | 209 | if(!error) | ||
504 | 210 | return TRUE; | ||
505 | 211 | if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE)) | ||
506 | 212 | g_warning("[Configuration] Failed to parse integer value [%s] %s: %s", group, key, error->message); | ||
507 | 213 | g_clear_error(&error); | ||
508 | 214 | return FALSE; | ||
509 | 215 | } | ||
510 | 216 | |||
511 | 217 | static gboolean | ||
512 | 218 | get_bool(GKeyFile* config, const gchar* group, const gchar* key, gboolean* out) | ||
513 | 219 | { | ||
514 | 220 | GError* error = NULL; | ||
515 | 221 | *out = g_key_file_get_boolean(config, group, key, &error); | ||
516 | 222 | if(!error) | ||
517 | 223 | return TRUE; | ||
518 | 224 | if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE)) | ||
519 | 225 | g_warning("[Configuration] Failed to parse boolean value [%s] %s: %s", group, key, error->message); | ||
520 | 226 | g_clear_error(&error); | ||
521 | 227 | return FALSE; | ||
522 | 228 | } | ||
523 | 229 | |||
524 | 230 | gchar** | ||
525 | 231 | config_get_groups(const gchar* prefix) | ||
526 | 232 | { | ||
527 | 233 | gsize groups_size = 0, i, next; | ||
528 | 234 | gchar** groups = g_key_file_get_groups(greeter_config, &groups_size); | ||
529 | 235 | |||
530 | 236 | for(i = next = 0; i < groups_size; ++i) | ||
531 | 237 | if(groups[i] && g_str_has_prefix(groups[i], prefix)) | ||
532 | 238 | { | ||
533 | 239 | if(i != next) | ||
534 | 240 | { | ||
535 | 241 | g_free (groups[next]); | ||
536 | 242 | groups[next] = groups[i]; | ||
537 | 243 | groups[i] = NULL; | ||
538 | 244 | } | ||
539 | 245 | ++next; | ||
540 | 246 | } | ||
541 | 247 | |||
542 | 248 | if(groups) | ||
543 | 249 | groups[next] = NULL; | ||
544 | 250 | |||
545 | 251 | return groups; | ||
546 | 252 | } | ||
547 | 253 | |||
548 | 254 | gboolean | ||
549 | 255 | config_has_key(const gchar* group, const gchar* key) | ||
550 | 256 | { | ||
551 | 257 | GKeyFile* file = get_file_for_group(&group); | ||
552 | 258 | return g_key_file_has_key(file, group, key, NULL); | ||
553 | 259 | } | ||
554 | 260 | |||
555 | 261 | gchar* | ||
556 | 262 | config_get_string(const gchar* group, const gchar* key, const gchar* fallback) | ||
557 | 263 | { | ||
558 | 264 | GKeyFile* file = get_file_for_group(&group); | ||
559 | 265 | gchar* value = g_key_file_get_value(file, group, key, NULL); | ||
560 | 266 | return value || !fallback ? value : g_strdup(fallback); | ||
561 | 267 | } | ||
562 | 268 | |||
563 | 269 | void | ||
564 | 270 | config_set_string(const gchar* group, const gchar* key, const gchar* value) | ||
565 | 271 | { | ||
566 | 272 | if(get_file_for_group(&group) != state_config) | ||
567 | 273 | { | ||
568 | 274 | g_warning("[Configuration] %s(%s, %s, '%s')", __func__, group, key, value); | ||
569 | 275 | return; | ||
570 | 276 | } | ||
571 | 277 | |||
572 | 278 | g_key_file_set_value(state_config, group, key, value); | ||
573 | 279 | save_key_file(state_config, state_filename); | ||
574 | 280 | } | ||
575 | 281 | |||
576 | 282 | gchar** | ||
577 | 283 | config_get_string_list(const gchar* group, const gchar* key, gchar** fallback) | ||
578 | 284 | { | ||
579 | 285 | GKeyFile* file = get_file_for_group(&group); | ||
580 | 286 | gchar** value = g_key_file_get_string_list(file, group, key, NULL, NULL); | ||
581 | 287 | return value || !fallback ? value : g_strdupv(fallback); | ||
582 | 288 | } | ||
583 | 289 | |||
584 | 290 | gint | ||
585 | 291 | config_get_int(const gchar* group, const gchar* key, gint fallback) | ||
586 | 292 | { | ||
587 | 293 | GKeyFile* file = get_file_for_group(&group); | ||
588 | 294 | gint value; | ||
589 | 295 | if(!get_int(file, group, key, &value)) | ||
590 | 296 | return fallback; | ||
591 | 297 | return value; | ||
592 | 298 | } | ||
593 | 299 | |||
594 | 300 | void | ||
595 | 301 | config_set_int(const gchar* group, const gchar* key, gint value) | ||
596 | 302 | { | ||
597 | 303 | if(get_file_for_group(&group) != state_config) | ||
598 | 304 | { | ||
599 | 305 | g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value); | ||
600 | 306 | return; | ||
601 | 307 | } | ||
602 | 308 | |||
603 | 309 | g_key_file_set_integer(state_config, group, key, value); | ||
604 | 310 | save_key_file(state_config, state_filename); | ||
605 | 311 | } | ||
606 | 312 | |||
607 | 313 | gboolean | ||
608 | 314 | config_get_bool(const gchar* group, const gchar* key, gboolean fallback) | ||
609 | 315 | { | ||
610 | 316 | GKeyFile* file = get_file_for_group(&group); | ||
611 | 317 | gboolean value; | ||
612 | 318 | if(!get_bool(file, group, key, &value)) | ||
613 | 319 | return fallback; | ||
614 | 320 | return value; | ||
615 | 321 | } | ||
616 | 322 | |||
617 | 323 | void | ||
618 | 324 | config_set_bool(const gchar* group, const gchar* key, gboolean value) | ||
619 | 325 | { | ||
620 | 326 | if(get_file_for_group(&group) != state_config) | ||
621 | 327 | { | ||
622 | 328 | g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value); | ||
623 | 329 | return; | ||
624 | 330 | } | ||
625 | 331 | |||
626 | 332 | g_key_file_set_boolean(state_config, group, key, value); | ||
627 | 333 | save_key_file(state_config, state_filename); | ||
628 | 334 | } | ||
629 | 335 | |||
630 | 336 | gint | ||
631 | 337 | config_get_enum(const gchar* group, const gchar* key, gint fallback, const gchar* first_item, ...) | ||
632 | 338 | { | ||
633 | 339 | if(!first_item) | ||
634 | 340 | return fallback; | ||
635 | 341 | |||
636 | 342 | GKeyFile* file = get_file_for_group(&group); | ||
637 | 343 | gchar* value = g_key_file_get_value(file, group, key, NULL); | ||
638 | 344 | |||
639 | 345 | if(!value) | ||
640 | 346 | return fallback; | ||
641 | 347 | |||
642 | 348 | va_list var_args; | ||
643 | 349 | va_start(var_args, first_item); | ||
644 | 350 | |||
645 | 351 | gboolean found = FALSE; | ||
646 | 352 | const gchar* item_name = first_item; | ||
647 | 353 | while(item_name) | ||
648 | 354 | { | ||
649 | 355 | gint item_value = va_arg(var_args, gint); | ||
650 | 356 | if(g_strcmp0(value, item_name) == 0) | ||
651 | 357 | { | ||
652 | 358 | found = TRUE; | ||
653 | 359 | fallback = item_value; | ||
654 | 360 | break; | ||
655 | 361 | } | ||
656 | 362 | item_name = va_arg(var_args, gchar*); | ||
657 | 363 | } | ||
658 | 364 | va_end(var_args); | ||
659 | 365 | |||
660 | 366 | if(!found) | ||
661 | 367 | g_warning("[Configuration] Failed to parse enum value [%s] %s: %s", group, key, value); | ||
662 | 368 | |||
663 | 369 | return fallback; | ||
664 | 370 | } | ||
665 | 371 | |||
666 | 0 | 372 | ||
667 | === added file 'src/greeterconfiguration.h' | |||
668 | --- src/greeterconfiguration.h 1970-01-01 00:00:00 +0000 | |||
669 | +++ src/greeterconfiguration.h 2015-03-29 05:44:39 +0000 | |||
670 | @@ -0,0 +1,57 @@ | |||
671 | 1 | |||
672 | 2 | #ifndef GREETER_CONFIGURATION_H | ||
673 | 3 | #define GREETER_CONFIGURATION_H | ||
674 | 4 | |||
675 | 5 | #include <glib.h> | ||
676 | 6 | |||
677 | 7 | |||
678 | 8 | #define CONFIG_GROUP_DEFAULT "greeter" | ||
679 | 9 | #define CONFIG_KEY_INDICATORS "indicators" | ||
680 | 10 | #define CONFIG_KEY_DEBUGGING "allow-debugging" | ||
681 | 11 | #define CONFIG_KEY_SCREENSAVER_TIMEOUT "screensaver-timeout" | ||
682 | 12 | #define CONFIG_KEY_THEME "theme-name" | ||
683 | 13 | #define CONFIG_KEY_ICON_THEME "icon-theme-name" | ||
684 | 14 | #define CONFIG_KEY_FONT "font-name" | ||
685 | 15 | #define CONFIG_KEY_DPI "xft-dpi" | ||
686 | 16 | #define CONFIG_KEY_ANTIALIAS "xft-antialias" | ||
687 | 17 | #define CONFIG_KEY_HINT_STYLE "xft-hintstyle" | ||
688 | 18 | #define CONFIG_KEY_RGBA "xft-rgba" | ||
689 | 19 | #define CONFIG_KEY_HIDE_USER_IMAGE "hide-user-image" | ||
690 | 20 | #define CONFIG_KEY_DEFAULT_USER_IMAGE "default-user-image" | ||
691 | 21 | #define CONFIG_KEY_KEYBOARD "keyboard" | ||
692 | 22 | #define CONFIG_KEY_READER "reader" | ||
693 | 23 | #define CONFIG_KEY_CLOCK_FORMAT "clock-format" | ||
694 | 24 | #define CONFIG_KEY_ACTIVE_MONITOR "active-monitor" | ||
695 | 25 | #define CONFIG_KEY_POSITION "position" | ||
696 | 26 | #define CONFIG_KEY_PANEL_POSITION "panel-position" | ||
697 | 27 | #define CONFIG_KEY_KEYBOARD_POSITION "keyboard-position" | ||
698 | 28 | #define CONFIG_KEY_A11Y_STATES "a11y-states" | ||
699 | 29 | |||
700 | 30 | #define CONFIG_GROUP_MONITOR "monitor:" | ||
701 | 31 | #define CONFIG_KEY_BACKGROUND "background" | ||
702 | 32 | #define CONFIG_KEY_USER_BACKGROUND "user-background" | ||
703 | 33 | #define CONFIG_KEY_LAPTOP "laptop" | ||
704 | 34 | #define CONFIG_KEY_T_TYPE "transition-type" | ||
705 | 35 | #define CONFIG_KEY_T_DURATION "transition-duration" | ||
706 | 36 | |||
707 | 37 | #define STATE_SECTION_GREETER "/greeter" | ||
708 | 38 | #define STATE_SECTION_A11Y "/a11y-states" | ||
709 | 39 | #define STATE_KEY_LAST_USER "last-user" | ||
710 | 40 | #define STATE_KEY_LAST_SESSION "last-session" | ||
711 | 41 | |||
712 | 42 | |||
713 | 43 | void config_init (void); | ||
714 | 44 | |||
715 | 45 | gchar** config_get_groups (const gchar* prefix); | ||
716 | 46 | gboolean config_has_key (const gchar* group, const gchar* key); | ||
717 | 47 | |||
718 | 48 | gchar* config_get_string (const gchar* group, const gchar* key, const gchar* fallback); | ||
719 | 49 | void config_set_string (const gchar* group, const gchar* key, const gchar* value); | ||
720 | 50 | gchar** config_get_string_list (const gchar* group, const gchar* key, gchar** fallback); | ||
721 | 51 | gint config_get_int (const gchar* group, const gchar* key, gint fallback); | ||
722 | 52 | void config_set_int (const gchar* group, const gchar* key, gint value); | ||
723 | 53 | gboolean config_get_bool (const gchar* group, const gchar* key, gboolean fallback); | ||
724 | 54 | void config_set_bool (const gchar* group, const gchar* key, gboolean value); | ||
725 | 55 | gint config_get_enum (const gchar* group, const gchar* key, gint fallback, const gchar* first_name, ...) G_GNUC_NULL_TERMINATED; | ||
726 | 56 | |||
727 | 57 | #endif //GREETER_CONFIGURATION_H | ||
728 | 0 | 58 | ||
729 | === modified file 'src/lightdm-gtk-greeter-fallback.css' | |||
730 | --- src/lightdm-gtk-greeter-fallback.css 2014-05-22 19:52:34 +0000 | |||
731 | +++ src/lightdm-gtk-greeter-fallback.css 2015-03-29 05:44:39 +0000 | |||
732 | @@ -1,12 +1,12 @@ | |||
733 | 1 | #layout_menuitem>GtkLabel | 1 | #layout_menuitem>GtkLabel |
734 | 2 | { | 2 | { |
739 | 3 | border: 1px solid alpha(@menu_fg_color, 0.8); | 3 | border: 1px solid alpha(@menu_fg_color, 0.8); |
740 | 4 | border-radius: 0.5em; | 4 | border-radius: 0.5em; |
741 | 5 | padding: 0px 0.25em; | 5 | padding: 0px 0.25em; |
742 | 6 | background: alpha(@menu_fg_color, 0.2); | 6 | background: alpha(@menu_fg_color, 0.2); |
743 | 7 | } | 7 | } |
744 | 8 | 8 | ||
745 | 9 | #layout_menuitem | 9 | #layout_menuitem |
746 | 10 | { | 10 | { |
748 | 11 | padding: 1px; | 11 | padding: 1px; |
749 | 12 | } | 12 | } |
750 | 13 | 13 | ||
751 | === modified file 'src/lightdm-gtk-greeter.c' | |||
752 | --- src/lightdm-gtk-greeter.c 2015-01-26 14:41:10 +0000 | |||
753 | +++ src/lightdm-gtk-greeter.c 2015-03-29 05:44:39 +0000 | |||
754 | @@ -47,19 +47,16 @@ | |||
755 | 47 | 47 | ||
756 | 48 | #include <lightdm.h> | 48 | #include <lightdm.h> |
757 | 49 | 49 | ||
758 | 50 | #include "src/greeterconfiguration.h" | ||
759 | 50 | #include "src/greetermenubar.h" | 51 | #include "src/greetermenubar.h" |
760 | 51 | #include "src/greeterbackground.h" | 52 | #include "src/greeterbackground.h" |
761 | 52 | #include "src/lightdm-gtk-greeter-ui.h" | 53 | #include "src/lightdm-gtk-greeter-ui.h" |
762 | 53 | #include "src/lightdm-gtk-greeter-css-fallback.h" | 54 | #include "src/lightdm-gtk-greeter-css-fallback.h" |
763 | 54 | #include "src/lightdm-gtk-greeter-css-application.h" | 55 | #include "src/lightdm-gtk-greeter-css-application.h" |
764 | 55 | 56 | ||
765 | 57 | |||
766 | 56 | static LightDMGreeter *greeter; | 58 | static LightDMGreeter *greeter; |
767 | 57 | 59 | ||
768 | 58 | /* State file */ | ||
769 | 59 | static GKeyFile *state; | ||
770 | 60 | static gchar *state_filename; | ||
771 | 61 | static void save_state_file (void); | ||
772 | 62 | |||
773 | 63 | /* List of spawned processes */ | 60 | /* List of spawned processes */ |
774 | 64 | static GSList *pids_to_close = NULL; | 61 | static GSList *pids_to_close = NULL; |
775 | 65 | static GPid spawn_argv_pid (gchar **argv, GSpawnFlags flags, gint *pfd, GError **perror); | 62 | static GPid spawn_argv_pid (gchar **argv, GSpawnFlags flags, gint *pfd, GError **perror); |
776 | @@ -70,7 +67,8 @@ | |||
777 | 70 | static void sigterm_cb (gpointer user_data); | 67 | static void sigterm_cb (gpointer user_data); |
778 | 71 | 68 | ||
779 | 72 | /* Screen window */ | 69 | /* Screen window */ |
781 | 73 | static GtkOverlay *screen_overlay; | 70 | static GtkOverlay *screen_overlay; |
782 | 71 | static GtkWidget *screen_overlay_child; | ||
783 | 74 | 72 | ||
784 | 75 | /* Login window */ | 73 | /* Login window */ |
785 | 76 | static GtkWidget *login_window; | 74 | static GtkWidget *login_window; |
786 | @@ -123,7 +121,7 @@ | |||
787 | 123 | DimensionPosition width, height; | 121 | DimensionPosition width, height; |
788 | 124 | } WindowPosition; | 122 | } WindowPosition; |
789 | 125 | 123 | ||
791 | 126 | static WindowPosition* key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value); | 124 | static WindowPosition* str_to_position (const gchar *str, const WindowPosition *default_value); |
792 | 127 | /* Function translate user defined coordinates to absolute value */ | 125 | /* Function translate user defined coordinates to absolute value */ |
793 | 128 | static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window); | 126 | static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window); |
794 | 129 | gboolean screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data); | 127 | gboolean screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data); |
795 | @@ -263,7 +261,7 @@ | |||
796 | 263 | /* Maybe unnecessary (in future) trick to enable accelerators for hidden/detached menu items */ | 261 | /* Maybe unnecessary (in future) trick to enable accelerators for hidden/detached menu items */ |
797 | 264 | static void reassign_menu_item_accel (GtkWidget *item); | 262 | static void reassign_menu_item_accel (GtkWidget *item); |
798 | 265 | 263 | ||
800 | 266 | static void init_indicators (GKeyFile* config); | 264 | static void init_indicators (void); |
801 | 267 | 265 | ||
802 | 268 | static void layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data); | 266 | static void layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data); |
803 | 269 | static void update_layouts_menu (void); | 267 | static void update_layouts_menu (void); |
804 | @@ -283,21 +281,42 @@ | |||
805 | 283 | void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data); | 281 | void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data); |
806 | 284 | void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data); | 282 | void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data); |
807 | 285 | 283 | ||
809 | 286 | /* Power indciator */ | 284 | /* Power indicator */ |
810 | 287 | static void power_menu_cb (GtkWidget *menuitem, gpointer userdata); | 285 | static void power_menu_cb (GtkWidget *menuitem, gpointer userdata); |
811 | 288 | void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter); | 286 | void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter); |
812 | 289 | void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter); | 287 | void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter); |
813 | 290 | void restart_cb (GtkWidget *widget, LightDMGreeter *greeter); | 288 | void restart_cb (GtkWidget *widget, LightDMGreeter *greeter); |
814 | 291 | void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter); | 289 | void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter); |
815 | 292 | 290 | ||
816 | 291 | static void read_monitor_configuration (const gchar *group, const gchar *name); | ||
817 | 292 | |||
818 | 293 | struct SavedFocusData | ||
819 | 294 | { | ||
820 | 295 | GtkWidget *widget; | ||
821 | 296 | gint editable_pos; | ||
822 | 297 | }; | ||
823 | 298 | |||
824 | 293 | gpointer greeter_save_focus(GtkWidget* widget); | 299 | gpointer greeter_save_focus(GtkWidget* widget); |
825 | 294 | void greeter_restore_focus(const gpointer saved_data); | 300 | void greeter_restore_focus(const gpointer saved_data); |
826 | 295 | 301 | ||
828 | 296 | struct SavedFocusData | 302 | |
829 | 303 | static void | ||
830 | 304 | read_monitor_configuration (const gchar *group, const gchar *name) | ||
831 | 297 | { | 305 | { |
835 | 298 | GtkWidget *widget; | 306 | g_debug ("[Configuration] Monitor configuration found: '%s'", name); |
836 | 299 | gint editable_pos; | 307 | |
837 | 300 | }; | 308 | gchar *background = config_get_string (group, CONFIG_KEY_BACKGROUND, NULL); |
838 | 309 | greeter_background_set_monitor_config (greeter_background, name, background, | ||
839 | 310 | config_get_bool (group, CONFIG_KEY_USER_BACKGROUND, -1), | ||
840 | 311 | config_get_bool (group, CONFIG_KEY_LAPTOP, -1), | ||
841 | 312 | config_get_int (group, CONFIG_KEY_T_DURATION, -1), | ||
842 | 313 | config_get_enum (group, CONFIG_KEY_T_TYPE, | ||
843 | 314 | TRANSITION_TYPE_FALLBACK, | ||
844 | 315 | "none", TRANSITION_TYPE_NONE, | ||
845 | 316 | "linear", TRANSITION_TYPE_LINEAR, | ||
846 | 317 | "ease-in-out", TRANSITION_TYPE_EASE_IN_OUT, NULL)); | ||
847 | 318 | g_free (background); | ||
848 | 319 | } | ||
849 | 301 | 320 | ||
850 | 302 | gpointer | 321 | gpointer |
851 | 303 | greeter_save_focus(GtkWidget* widget) | 322 | greeter_save_focus(GtkWidget* widget) |
852 | @@ -316,43 +335,16 @@ | |||
853 | 316 | void | 335 | void |
854 | 317 | greeter_restore_focus(const gpointer saved_data) | 336 | greeter_restore_focus(const gpointer saved_data) |
855 | 318 | { | 337 | { |
856 | 319 | if (!saved_data) | ||
857 | 320 | return; | ||
858 | 321 | |||
859 | 322 | struct SavedFocusData *data = saved_data; | 338 | struct SavedFocusData *data = saved_data; |
862 | 323 | if (GTK_IS_WIDGET (data->widget)) | 339 | |
863 | 324 | gtk_widget_grab_focus (data->widget); | 340 | if (!saved_data || !GTK_IS_WIDGET (data->widget)) |
864 | 341 | return; | ||
865 | 342 | |||
866 | 343 | gtk_widget_grab_focus (data->widget); | ||
867 | 325 | if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1) | 344 | if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1) |
868 | 326 | gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos); | 345 | gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos); |
869 | 327 | } | 346 | } |
870 | 328 | 347 | ||
871 | 329 | /* State file */ | ||
872 | 330 | |||
873 | 331 | static void | ||
874 | 332 | save_state_file (void) | ||
875 | 333 | { | ||
876 | 334 | GError *error = NULL; | ||
877 | 335 | gsize data_length = 0; | ||
878 | 336 | gchar *data = g_key_file_to_data (state, &data_length, &error); | ||
879 | 337 | |||
880 | 338 | if (error) | ||
881 | 339 | { | ||
882 | 340 | g_warning ("Failed to save state file: %s", error->message); | ||
883 | 341 | g_clear_error (&error); | ||
884 | 342 | } | ||
885 | 343 | |||
886 | 344 | if (data) | ||
887 | 345 | { | ||
888 | 346 | g_file_set_contents (state_filename, data, data_length, &error); | ||
889 | 347 | if (error) | ||
890 | 348 | { | ||
891 | 349 | g_warning ("Failed to save state file: %s", error->message); | ||
892 | 350 | g_clear_error (&error); | ||
893 | 351 | } | ||
894 | 352 | g_free (data); | ||
895 | 353 | } | ||
896 | 354 | } | ||
897 | 355 | |||
898 | 356 | /* Terminating */ | 348 | /* Terminating */ |
899 | 357 | 349 | ||
900 | 358 | static GPid | 350 | static GPid |
901 | @@ -564,15 +556,14 @@ | |||
902 | 564 | } | 556 | } |
903 | 565 | 557 | ||
904 | 566 | static WindowPosition* | 558 | static WindowPosition* |
906 | 567 | key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value) | 559 | str_to_position (const gchar *str, const WindowPosition *default_value) |
907 | 568 | { | 560 | { |
908 | 569 | WindowPosition* pos = g_new0 (WindowPosition, 1); | 561 | WindowPosition* pos = g_new0 (WindowPosition, 1); |
909 | 570 | gchar *value = g_key_file_get_value (key_file, group_name, key, NULL); | ||
910 | 571 | |||
911 | 572 | *pos = *default_value; | 562 | *pos = *default_value; |
912 | 573 | 563 | ||
914 | 574 | if (value) | 564 | if (str) |
915 | 575 | { | 565 | { |
916 | 566 | gchar *value = g_strdup (str); | ||
917 | 576 | gchar *x = value; | 567 | gchar *x = value; |
918 | 577 | gchar *y = strchr (value, ' '); | 568 | gchar *y = strchr (value, ' '); |
919 | 578 | if (y) | 569 | if (y) |
920 | @@ -732,7 +723,7 @@ | |||
921 | 732 | } | 723 | } |
922 | 733 | else | 724 | else |
923 | 734 | { | 725 | { |
925 | 735 | g_warning ("Failed to load user image: %s", error->message); | 726 | g_debug ("Failed to load user image: %s", error->message); |
926 | 736 | g_clear_error (&error); | 727 | g_clear_error (&error); |
927 | 737 | } | 728 | } |
928 | 738 | } | 729 | } |
929 | @@ -849,6 +840,7 @@ | |||
930 | 849 | if (id != 0 && end_ptr > text) | 840 | if (id != 0 && end_ptr > text) |
931 | 850 | { | 841 | { |
932 | 851 | socket = GTK_SOCKET (gtk_socket_new ()); | 842 | socket = GTK_SOCKET (gtk_socket_new ()); |
933 | 843 | gtk_container_foreach (GTK_CONTAINER (command->widget), (GtkCallback)gtk_widget_destroy, NULL); | ||
934 | 852 | gtk_container_add (GTK_CONTAINER (command->widget), GTK_WIDGET (socket)); | 844 | gtk_container_add (GTK_CONTAINER (command->widget), GTK_WIDGET (socket)); |
935 | 853 | gtk_socket_add_id (socket, id); | 845 | gtk_socket_add_id (socket, id); |
936 | 854 | gtk_widget_show_all (GTK_WIDGET (command->widget)); | 846 | gtk_widget_show_all (GTK_WIDGET (command->widget)); |
937 | @@ -879,6 +871,7 @@ | |||
938 | 879 | g_warning ("[Command/%s] Failed to run: %s", command->name, error->message); | 871 | g_warning ("[Command/%s] Failed to run: %s", command->name, error->message); |
939 | 880 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE); | 872 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE); |
940 | 881 | } | 873 | } |
941 | 874 | |||
942 | 882 | g_clear_error (&error); | 875 | g_clear_error (&error); |
943 | 883 | 876 | ||
944 | 884 | return command->pid; | 877 | return command->pid; |
945 | @@ -911,8 +904,7 @@ | |||
946 | 911 | static void | 904 | static void |
947 | 912 | a11y_menuitem_toggled_cb (GtkCheckMenuItem *item, const gchar* name) | 905 | a11y_menuitem_toggled_cb (GtkCheckMenuItem *item, const gchar* name) |
948 | 913 | { | 906 | { |
951 | 914 | g_key_file_set_boolean (state, "a11y-states", name, gtk_check_menu_item_get_active (item)); | 907 | config_set_bool (STATE_SECTION_A11Y, name, gtk_check_menu_item_get_active (item)); |
950 | 915 | save_state_file (); | ||
952 | 916 | } | 908 | } |
953 | 917 | 909 | ||
954 | 918 | /* Session */ | 910 | /* Session */ |
955 | @@ -942,7 +934,7 @@ | |||
956 | 942 | if (!session || !is_valid_session (sessions, session)) | 934 | if (!session || !is_valid_session (sessions, session)) |
957 | 943 | { | 935 | { |
958 | 944 | /* previous session */ | 936 | /* previous session */ |
960 | 945 | last_session = g_key_file_get_value (state, "greeter", "last-session", NULL); | 937 | last_session = config_get_string (STATE_SECTION_GREETER, STATE_KEY_LAST_SESSION, NULL); |
961 | 946 | if (last_session && g_strcmp0 (session, last_session) != 0 && | 938 | if (last_session && g_strcmp0 (session, last_session) != 0 && |
962 | 947 | is_valid_session (sessions, last_session)) | 939 | is_valid_session (sessions, last_session)) |
963 | 948 | session = last_session; | 940 | session = last_session; |
964 | @@ -1410,9 +1402,8 @@ | |||
965 | 1410 | } | 1402 | } |
966 | 1411 | 1403 | ||
967 | 1412 | static void | 1404 | static void |
969 | 1413 | init_indicators (GKeyFile* config) | 1405 | init_indicators (void) |
970 | 1414 | { | 1406 | { |
971 | 1415 | gchar **names = NULL; | ||
972 | 1416 | gsize length = 0; | 1407 | gsize length = 0; |
973 | 1417 | guint i; | 1408 | guint i; |
974 | 1418 | GHashTable *builtin_items = NULL; | 1409 | GHashTable *builtin_items = NULL; |
975 | @@ -1421,27 +1412,14 @@ | |||
976 | 1421 | #ifdef HAVE_LIBINDICATOR | 1412 | #ifdef HAVE_LIBINDICATOR |
977 | 1422 | gboolean inited = FALSE; | 1413 | gboolean inited = FALSE; |
978 | 1423 | #endif | 1414 | #endif |
979 | 1424 | gboolean fallback = FALSE; | ||
980 | 1425 | 1415 | ||
981 | 1426 | const gchar *DEFAULT_LAYOUT[] = {"~host", "~spacer", "~clock", "~spacer", | 1416 | const gchar *DEFAULT_LAYOUT[] = {"~host", "~spacer", "~clock", "~spacer", |
982 | 1427 | "~session", "~language", "~a11y", "~power", NULL}; | 1417 | "~session", "~language", "~a11y", "~power", NULL}; |
983 | 1428 | 1418 | ||
997 | 1429 | if (g_key_file_has_key (config, "greeter", "indicators", NULL)) | 1419 | gchar **names = config_get_string_list (NULL, CONFIG_KEY_INDICATORS, NULL); |
998 | 1430 | { /* no option = default list, empty value = empty list */ | 1420 | if (!names) |
986 | 1431 | names = g_key_file_get_string_list (config, "greeter", "indicators", &length, NULL); | ||
987 | 1432 | } | ||
988 | 1433 | else if (g_key_file_has_key (config, "greeter", "show-indicators", NULL)) | ||
989 | 1434 | { /* fallback mode: no option = empty value = default list */ | ||
990 | 1435 | names = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL); | ||
991 | 1436 | if (length == 0) | ||
992 | 1437 | fallback = TRUE; | ||
993 | 1438 | } | ||
994 | 1439 | |||
995 | 1440 | if (!names || fallback) | ||
996 | 1441 | { | ||
999 | 1442 | names = (gchar**)DEFAULT_LAYOUT; | 1421 | names = (gchar**)DEFAULT_LAYOUT; |
1002 | 1443 | length = g_strv_length (names); | 1422 | length = g_strv_length (names); |
1001 | 1444 | } | ||
1003 | 1445 | 1423 | ||
1004 | 1446 | builtin_items = g_hash_table_new (g_str_hash, g_str_equal); | 1424 | builtin_items = g_hash_table_new (g_str_hash, g_str_equal); |
1005 | 1447 | 1425 | ||
1006 | @@ -1925,8 +1903,7 @@ | |||
1007 | 1925 | pending_questions = NULL; | 1903 | pending_questions = NULL; |
1008 | 1926 | } | 1904 | } |
1009 | 1927 | 1905 | ||
1012 | 1928 | g_key_file_set_value (state, "greeter", "last-user", username); | 1906 | config_set_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, username); |
1011 | 1929 | save_state_file (); | ||
1013 | 1930 | 1907 | ||
1014 | 1931 | if (g_strcmp0 (username, "*other") == 0) | 1908 | if (g_strcmp0 (username, "*other") == 0) |
1015 | 1932 | { | 1909 | { |
1016 | @@ -2018,8 +1995,7 @@ | |||
1017 | 2018 | session = get_session (); | 1995 | session = get_session (); |
1018 | 2019 | 1996 | ||
1019 | 2020 | /* Remember last choice */ | 1997 | /* Remember last choice */ |
1022 | 2021 | g_key_file_set_value (state, "greeter", "last-session", session); | 1998 | config_set_string (STATE_SECTION_GREETER, STATE_KEY_LAST_SESSION, session); |
1021 | 2022 | save_state_file (); | ||
1023 | 2023 | 1999 | ||
1024 | 2024 | greeter_background_save_xroot (greeter_background); | 2000 | greeter_background_save_xroot (greeter_background); |
1025 | 2025 | 2001 | ||
1026 | @@ -2436,7 +2412,6 @@ | |||
1027 | 2436 | const GList *items, *item; | 2412 | const GList *items, *item; |
1028 | 2437 | GtkTreeModel *model; | 2413 | GtkTreeModel *model; |
1029 | 2438 | GtkTreeIter iter; | 2414 | GtkTreeIter iter; |
1030 | 2439 | gchar *last_user; | ||
1031 | 2440 | const gchar *selected_user; | 2415 | const gchar *selected_user; |
1032 | 2441 | gboolean logged_in = FALSE; | 2416 | gboolean logged_in = FALSE; |
1033 | 2442 | 2417 | ||
1034 | @@ -2474,7 +2449,7 @@ | |||
1035 | 2474 | 2, PANGO_WEIGHT_NORMAL, | 2449 | 2, PANGO_WEIGHT_NORMAL, |
1036 | 2475 | -1); | 2450 | -1); |
1037 | 2476 | 2451 | ||
1039 | 2477 | last_user = g_key_file_get_value (state, "greeter", "last-user", NULL); | 2452 | gchar *last_user = config_get_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, NULL); |
1040 | 2478 | 2453 | ||
1041 | 2479 | if (lightdm_greeter_get_select_user_hint (greeter)) | 2454 | if (lightdm_greeter_get_select_user_hint (greeter)) |
1042 | 2480 | selected_user = lightdm_greeter_get_select_user_hint (greeter); | 2455 | selected_user = lightdm_greeter_get_select_user_hint (greeter); |
1043 | @@ -2513,54 +2488,40 @@ | |||
1044 | 2513 | set_displayed_user (greeter, name); | 2488 | set_displayed_user (greeter, name); |
1045 | 2514 | g_free (name); | 2489 | g_free (name); |
1046 | 2515 | } | 2490 | } |
1047 | 2516 | |||
1048 | 2517 | } | 2491 | } |
1049 | 2518 | 2492 | ||
1050 | 2519 | g_free (last_user); | 2493 | g_free (last_user); |
1051 | 2520 | } | 2494 | } |
1052 | 2521 | 2495 | ||
1053 | 2522 | static GdkFilterReturn | 2496 | static GdkFilterReturn |
1055 | 2523 | focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data) | 2497 | wm_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data) |
1056 | 2524 | { | 2498 | { |
1060 | 2525 | XEvent* xevent = (XEvent*)gxevent; | 2499 | XEvent *xevent = (XEvent*)gxevent; |
1058 | 2526 | GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ? | ||
1059 | 2527 | gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL; | ||
1061 | 2528 | if (xevent->type == MapNotify) | 2500 | if (xevent->type == MapNotify) |
1062 | 2529 | { | 2501 | { |
1067 | 2530 | Window xwin = xevent->xmap.window; | 2502 | GdkDisplay *display = gdk_x11_lookup_xdisplay (xevent->xmap.display); |
1068 | 2531 | Window keyboard_xid = 0; | 2503 | GdkWindow *win = gdk_x11_window_foreign_new_for_display (display, xevent->xmap.window); |
1065 | 2532 | GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display); | ||
1066 | 2533 | GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin); | ||
1069 | 2534 | GdkWindowTypeHint win_type = gdk_window_get_type_hint (win); | 2504 | GdkWindowTypeHint win_type = gdk_window_get_type_hint (win); |
1070 | 2535 | 2505 | ||
1079 | 2536 | /* Check to see if this window is our onboard window, since we don't want to focus it. */ | 2506 | if (win_type != GDK_WINDOW_TYPE_HINT_COMBO && |
1080 | 2537 | if (keyboard_win) | 2507 | win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP && |
1081 | 2538 | keyboard_xid = gdk_x11_window_get_xid (keyboard_win); | 2508 | win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION) |
1082 | 2539 | 2509 | /* | |
1083 | 2540 | if (xwin != keyboard_xid | 2510 | if (win_type == GDK_WINDOW_TYPE_HINT_DESKTOP || |
1084 | 2541 | && win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP | 2511 | win_type == GDK_WINDOW_TYPE_HINT_DIALOG) |
1085 | 2542 | && win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION) | 2512 | */ |
1078 | 2543 | { | ||
1086 | 2544 | gdk_window_focus (win, GDK_CURRENT_TIME); | 2513 | gdk_window_focus (win, GDK_CURRENT_TIME); |
1087 | 2545 | /* Make sure to keep keyboard above */ | ||
1088 | 2546 | if (keyboard_win) | ||
1089 | 2547 | gdk_window_raise (keyboard_win); | ||
1090 | 2548 | } | ||
1091 | 2549 | } | 2514 | } |
1092 | 2550 | else if (xevent->type == UnmapNotify) | 2515 | else if (xevent->type == UnmapNotify) |
1093 | 2551 | { | 2516 | { |
1094 | 2552 | Window xwin; | 2517 | Window xwin; |
1096 | 2553 | int revert_to; | 2518 | int revert_to = RevertToNone; |
1097 | 2519 | |||
1098 | 2554 | XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to); | 2520 | XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to); |
1099 | 2555 | |||
1100 | 2556 | if (revert_to == RevertToNone) | 2521 | if (revert_to == RevertToNone) |
1107 | 2557 | { | 2522 | gdk_window_lower (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay)))); |
1102 | 2558 | gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME); | ||
1103 | 2559 | /* Make sure to keep keyboard above */ | ||
1104 | 2560 | if (keyboard_win) | ||
1105 | 2561 | gdk_window_raise (keyboard_win); | ||
1106 | 2562 | } | ||
1108 | 2563 | } | 2523 | } |
1109 | 2524 | |||
1110 | 2564 | return GDK_FILTER_CONTINUE; | 2525 | return GDK_FILTER_CONTINUE; |
1111 | 2565 | } | 2526 | } |
1112 | 2566 | 2527 | ||
1113 | @@ -2583,19 +2544,19 @@ | |||
1114 | 2583 | int | 2544 | int |
1115 | 2584 | main (int argc, char **argv) | 2545 | main (int argc, char **argv) |
1116 | 2585 | { | 2546 | { |
1117 | 2586 | GKeyFile *config; | ||
1118 | 2587 | GtkBuilder *builder; | 2547 | GtkBuilder *builder; |
1119 | 2588 | const GList *items, *item; | 2548 | const GList *items, *item; |
1120 | 2589 | GtkWidget *image; | 2549 | GtkWidget *image; |
1122 | 2590 | gchar *value, **values, *state_dir; | 2550 | gchar *value; |
1123 | 2591 | GtkIconTheme *icon_theme; | 2551 | GtkIconTheme *icon_theme; |
1124 | 2592 | GtkCssProvider *css_provider; | 2552 | GtkCssProvider *css_provider; |
1125 | 2593 | GError *error = NULL; | 2553 | GError *error = NULL; |
1126 | 2594 | Display *display; | ||
1127 | 2595 | 2554 | ||
1128 | 2596 | /* Prevent memory from being swapped out, as we are dealing with passwords */ | 2555 | /* Prevent memory from being swapped out, as we are dealing with passwords */ |
1129 | 2597 | mlockall (MCL_CURRENT | MCL_FUTURE); | 2556 | mlockall (MCL_CURRENT | MCL_FUTURE); |
1130 | 2598 | 2557 | ||
1131 | 2558 | g_message ("Starting %s (%s, %s)", PACKAGE_STRING, __DATE__, __TIME__); | ||
1132 | 2559 | |||
1133 | 2599 | /* Disable global menus */ | 2560 | /* Disable global menus */ |
1134 | 2600 | g_unsetenv ("UBUNTU_MENUPROXY"); | 2561 | g_unsetenv ("UBUNTU_MENUPROXY"); |
1135 | 2601 | 2562 | ||
1136 | @@ -2613,13 +2574,9 @@ | |||
1137 | 2613 | 2574 | ||
1138 | 2614 | g_unix_signal_add (SIGTERM, (GSourceFunc)sigterm_cb, NULL); | 2575 | g_unix_signal_add (SIGTERM, (GSourceFunc)sigterm_cb, NULL); |
1139 | 2615 | 2576 | ||
1145 | 2616 | config = g_key_file_new (); | 2577 | config_init (); |
1141 | 2617 | g_key_file_load_from_file (config, CONFIG_FILE, G_KEY_FILE_NONE, &error); | ||
1142 | 2618 | if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | ||
1143 | 2619 | g_warning ("Failed to load configuration from %s: %s\n", CONFIG_FILE, error->message); | ||
1144 | 2620 | g_clear_error (&error); | ||
1146 | 2621 | 2578 | ||
1148 | 2622 | if (g_key_file_get_boolean (config, "greeter", "allow-debugging", NULL)) | 2579 | if (config_get_bool (NULL, CONFIG_KEY_DEBUGGING, FALSE)) |
1149 | 2623 | g_log_set_default_handler (debug_log_handler, NULL); | 2580 | g_log_set_default_handler (debug_log_handler, NULL); |
1150 | 2624 | 2581 | ||
1151 | 2625 | /* init gtk */ | 2582 | /* init gtk */ |
1152 | @@ -2628,7 +2585,7 @@ | |||
1153 | 2628 | /* Disabling GtkInspector shortcuts. | 2585 | /* Disabling GtkInspector shortcuts. |
1154 | 2629 | It is still possible to run GtkInspector with GTK_DEBUG=interactive. | 2586 | It is still possible to run GtkInspector with GTK_DEBUG=interactive. |
1155 | 2630 | Assume that user knows what he's doing. */ | 2587 | Assume that user knows what he's doing. */ |
1157 | 2631 | if (!g_key_file_get_boolean (config, "greeter", "allow-debugging", NULL)) | 2588 | if (!config_get_bool (NULL, CONFIG_KEY_DEBUGGING, FALSE)) |
1158 | 2632 | { | 2589 | { |
1159 | 2633 | GtkWidget *fake_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); | 2590 | GtkWidget *fake_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); |
1160 | 2634 | GtkBindingSet *set = gtk_binding_set_by_class (G_OBJECT_GET_CLASS (fake_window)); | 2591 | GtkBindingSet *set = gtk_binding_set_by_class (G_OBJECT_GET_CLASS (fake_window)); |
1161 | @@ -2660,20 +2617,10 @@ | |||
1162 | 2660 | } | 2617 | } |
1163 | 2661 | 2618 | ||
1164 | 2662 | #ifdef HAVE_LIBIDO | 2619 | #ifdef HAVE_LIBIDO |
1165 | 2620 | g_debug ("Initializing IDO library"); | ||
1166 | 2663 | ido_init (); | 2621 | ido_init (); |
1167 | 2664 | #endif | 2622 | #endif |
1168 | 2665 | 2623 | ||
1169 | 2666 | state_dir = g_build_filename (g_get_user_cache_dir (), "lightdm-gtk-greeter", NULL); | ||
1170 | 2667 | g_mkdir_with_parents (state_dir, 0775); | ||
1171 | 2668 | state_filename = g_build_filename (state_dir, "state", NULL); | ||
1172 | 2669 | g_free (state_dir); | ||
1173 | 2670 | |||
1174 | 2671 | state = g_key_file_new (); | ||
1175 | 2672 | g_key_file_load_from_file (state, state_filename, G_KEY_FILE_NONE, &error); | ||
1176 | 2673 | if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | ||
1177 | 2674 | g_warning ("Failed to load state from %s: %s\n", state_filename, error->message); | ||
1178 | 2675 | g_clear_error (&error); | ||
1179 | 2676 | |||
1180 | 2677 | greeter = lightdm_greeter_new (); | 2624 | greeter = lightdm_greeter_new (); |
1181 | 2678 | g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL); | 2625 | g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL); |
1182 | 2679 | g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL); | 2626 | g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL); |
1183 | @@ -2686,69 +2633,65 @@ | |||
1184 | 2686 | gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR)); | 2633 | gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR)); |
1185 | 2687 | 2634 | ||
1186 | 2688 | /* Make the greeter behave a bit more like a screensaver if used as un/lock-screen by blanking the screen */ | 2635 | /* Make the greeter behave a bit more like a screensaver if used as un/lock-screen by blanking the screen */ |
1187 | 2689 | gchar* end_ptr = NULL; | ||
1188 | 2690 | int screensaver_timeout = 60; | ||
1189 | 2691 | value = g_key_file_get_value (config, "greeter", "screensaver-timeout", NULL); | ||
1190 | 2692 | if (value) | ||
1191 | 2693 | screensaver_timeout = g_ascii_strtoll (value, &end_ptr, 0); | ||
1192 | 2694 | g_free (value); | ||
1193 | 2695 | |||
1194 | 2696 | display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); | ||
1195 | 2697 | if (lightdm_greeter_get_lock_hint (greeter)) | 2636 | if (lightdm_greeter_get_lock_hint (greeter)) |
1196 | 2698 | { | 2637 | { |
1197 | 2638 | Display *display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); | ||
1198 | 2699 | XGetScreenSaver (display, &timeout, &interval, &prefer_blanking, &allow_exposures); | 2639 | XGetScreenSaver (display, &timeout, &interval, &prefer_blanking, &allow_exposures); |
1199 | 2700 | XForceScreenSaver (display, ScreenSaverActive); | 2640 | XForceScreenSaver (display, ScreenSaverActive); |
1201 | 2701 | XSetScreenSaver (display, screensaver_timeout, 0, ScreenSaverActive, DefaultExposures); | 2641 | XSetScreenSaver (display, config_get_int (NULL, CONFIG_KEY_SCREENSAVER_TIMEOUT, 60), 0, |
1202 | 2642 | ScreenSaverActive, DefaultExposures); | ||
1203 | 2702 | } | 2643 | } |
1204 | 2703 | 2644 | ||
1205 | 2704 | /* Set GTK+ settings */ | 2645 | /* Set GTK+ settings */ |
1207 | 2705 | value = g_key_file_get_value (config, "greeter", "theme-name", NULL); | 2646 | value = config_get_string (NULL, CONFIG_KEY_THEME, NULL); |
1208 | 2706 | if (value) | 2647 | if (value) |
1209 | 2707 | { | 2648 | { |
1211 | 2708 | g_debug ("Using Gtk+ theme %s", value); | 2649 | g_debug ("[Configuration] Changing GTK+ theme to '%s'", value); |
1212 | 2709 | g_object_set (gtk_settings_get_default (), "gtk-theme-name", value, NULL); | 2650 | g_object_set (gtk_settings_get_default (), "gtk-theme-name", value, NULL); |
1213 | 2651 | g_free (value); | ||
1214 | 2710 | } | 2652 | } |
1215 | 2711 | g_free (value); | ||
1216 | 2712 | g_object_get (gtk_settings_get_default (), "gtk-theme-name", &default_theme_name, NULL); | 2653 | g_object_get (gtk_settings_get_default (), "gtk-theme-name", &default_theme_name, NULL); |
1218 | 2713 | g_debug ("Default Gtk+ theme is '%s'", default_theme_name); | 2654 | g_debug ("[Configuration] GTK+ theme: '%s'", default_theme_name); |
1219 | 2714 | 2655 | ||
1221 | 2715 | value = g_key_file_get_value (config, "greeter", "icon-theme-name", NULL); | 2656 | value = config_get_string (NULL, CONFIG_KEY_ICON_THEME, NULL); |
1222 | 2716 | if (value) | 2657 | if (value) |
1223 | 2717 | { | 2658 | { |
1225 | 2718 | g_debug ("Using icon theme %s", value); | 2659 | g_debug ("[Configuration] Changing icons theme to '%s'", value); |
1226 | 2719 | g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", value, NULL); | 2660 | g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", value, NULL); |
1227 | 2661 | g_free (value); | ||
1228 | 2720 | } | 2662 | } |
1229 | 2721 | g_free (value); | ||
1230 | 2722 | g_object_get (gtk_settings_get_default (), "gtk-icon-theme-name", &default_icon_theme_name, NULL); | 2663 | g_object_get (gtk_settings_get_default (), "gtk-icon-theme-name", &default_icon_theme_name, NULL); |
1232 | 2723 | g_debug ("Default theme is '%s'", default_icon_theme_name); | 2664 | g_debug ("[Configuration] Icons theme: '%s'", default_icon_theme_name); |
1233 | 2724 | 2665 | ||
1235 | 2725 | value = g_key_file_get_value (config, "greeter", "font-name", NULL); | 2666 | value = config_get_string (NULL, CONFIG_KEY_FONT, "Sans 10"); |
1236 | 2726 | if (value) | 2667 | if (value) |
1237 | 2727 | { | 2668 | { |
1245 | 2728 | g_debug ("Using font %s", value); | 2669 | g_debug ("[Configuration] Changing font to '%s'", value); |
1246 | 2729 | g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL); | 2670 | g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL); |
1247 | 2730 | } | 2671 | g_free (value); |
1241 | 2731 | else | ||
1242 | 2732 | { | ||
1243 | 2733 | value = g_strdup ("Sans 10"); | ||
1244 | 2734 | g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL); | ||
1248 | 2735 | } | 2672 | } |
1249 | 2736 | g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL); | 2673 | g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL); |
1259 | 2737 | value = g_key_file_get_value (config, "greeter", "xft-dpi", NULL); | 2674 | g_debug ("[Configuration] Font: '%s'", default_font_name); |
1260 | 2738 | if (value) | 2675 | |
1261 | 2739 | g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", (int) (1024 * atof (value)), NULL); | 2676 | if (config_has_key (NULL, CONFIG_KEY_DPI)) |
1262 | 2740 | value = g_key_file_get_value (config, "greeter", "xft-antialias", NULL); | 2677 | g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", 1024*config_get_int (NULL, CONFIG_KEY_DPI, 96), NULL); |
1263 | 2741 | if (value) | 2678 | |
1264 | 2742 | g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", g_strcmp0 (value, "true") == 0, NULL); | 2679 | if (config_has_key (NULL, CONFIG_KEY_ANTIALIAS)) |
1265 | 2743 | g_free (value); | 2680 | g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", config_get_bool (NULL, CONFIG_KEY_ANTIALIAS, FALSE), NULL); |
1266 | 2744 | value = g_key_file_get_value (config, "greeter", "xft-hintstyle", NULL); | 2681 | |
1267 | 2745 | if (value) | 2682 | value = config_get_string (NULL, CONFIG_KEY_HINT_STYLE, NULL); |
1268 | 2683 | if (value) | ||
1269 | 2684 | { | ||
1270 | 2746 | g_object_set (gtk_settings_get_default (), "gtk-xft-hintstyle", value, NULL); | 2685 | g_object_set (gtk_settings_get_default (), "gtk-xft-hintstyle", value, NULL); |
1273 | 2747 | g_free (value); | 2686 | g_free (value); |
1274 | 2748 | value = g_key_file_get_value (config, "greeter", "xft-rgba", NULL); | 2687 | } |
1275 | 2688 | |||
1276 | 2689 | value = config_get_string (NULL, CONFIG_KEY_RGBA, NULL); | ||
1277 | 2749 | if (value) | 2690 | if (value) |
1278 | 2691 | { | ||
1279 | 2750 | g_object_set (gtk_settings_get_default (), "gtk-xft-rgba", value, NULL); | 2692 | g_object_set (gtk_settings_get_default (), "gtk-xft-rgba", value, NULL); |
1281 | 2751 | g_free (value); | 2693 | g_free (value); |
1282 | 2694 | } | ||
1283 | 2752 | 2695 | ||
1284 | 2753 | #ifdef AT_SPI_COMMAND | 2696 | #ifdef AT_SPI_COMMAND |
1285 | 2754 | spawn_line_pid (AT_SPI_COMMAND, G_SPAWN_SEARCH_PATH, NULL); | 2697 | spawn_line_pid (AT_SPI_COMMAND, G_SPAWN_SEARCH_PATH, NULL); |
1286 | @@ -2769,6 +2712,7 @@ | |||
1287 | 2769 | 2712 | ||
1288 | 2770 | /* Screen window */ | 2713 | /* Screen window */ |
1289 | 2771 | screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay")); | 2714 | screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay")); |
1290 | 2715 | screen_overlay_child = GTK_WIDGET (gtk_builder_get_object (builder, "screen_overlay_child")); | ||
1291 | 2772 | 2716 | ||
1292 | 2773 | /* Login window */ | 2717 | /* Login window */ |
1293 | 2774 | login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window")); | 2718 | login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window")); |
1294 | @@ -2817,7 +2761,7 @@ | |||
1295 | 2817 | gtk_accel_map_add_entry ("<Login>/a11y/reader", GDK_KEY_F4, 0); | 2761 | gtk_accel_map_add_entry ("<Login>/a11y/reader", GDK_KEY_F4, 0); |
1296 | 2818 | gtk_accel_map_add_entry ("<Login>/power/shutdown", GDK_KEY_F4, GDK_MOD1_MASK); | 2762 | gtk_accel_map_add_entry ("<Login>/power/shutdown", GDK_KEY_F4, GDK_MOD1_MASK); |
1297 | 2819 | 2763 | ||
1299 | 2820 | init_indicators (config); | 2764 | init_indicators (); |
1300 | 2821 | 2765 | ||
1301 | 2822 | /* Hide empty panel */ | 2766 | /* Hide empty panel */ |
1302 | 2823 | GList *menubar_items = gtk_container_get_children (GTK_CONTAINER (menubar)); | 2767 | GList *menubar_items = gtk_container_get_children (GTK_CONTAINER (menubar)); |
1303 | @@ -2826,7 +2770,7 @@ | |||
1304 | 2826 | else | 2770 | else |
1305 | 2827 | g_list_free (menubar_items); | 2771 | g_list_free (menubar_items); |
1306 | 2828 | 2772 | ||
1308 | 2829 | if (g_key_file_get_boolean (config, "greeter", "hide-user-image", NULL)) | 2773 | if (config_get_bool (NULL, CONFIG_KEY_HIDE_USER_IMAGE, FALSE)) |
1309 | 2830 | { | 2774 | { |
1310 | 2831 | gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "user_image_border"))); | 2775 | gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "user_image_border"))); |
1311 | 2832 | gtk_widget_hide (GTK_WIDGET (user_image)); /* Hide to mark image is disabled */ | 2776 | gtk_widget_hide (GTK_WIDGET (user_image)); /* Hide to mark image is disabled */ |
1312 | @@ -2834,7 +2778,7 @@ | |||
1313 | 2834 | } | 2778 | } |
1314 | 2835 | else | 2779 | else |
1315 | 2836 | { | 2780 | { |
1317 | 2837 | value = g_key_file_get_value (config, "greeter", "default-user-image", NULL); | 2781 | value = config_get_string (NULL, CONFIG_KEY_DEFAULT_USER_IMAGE, NULL); |
1318 | 2838 | if (value) | 2782 | if (value) |
1319 | 2839 | { | 2783 | { |
1320 | 2840 | if (value[0] == '#') | 2784 | if (value[0] == '#') |
1321 | @@ -2929,16 +2873,23 @@ | |||
1322 | 2929 | gtk_container_add (GTK_CONTAINER (a11y_menuitem), image); | 2873 | gtk_container_add (GTK_CONTAINER (a11y_menuitem), image); |
1323 | 2930 | } | 2874 | } |
1324 | 2931 | 2875 | ||
1329 | 2932 | value = g_key_file_get_value (config, "greeter", "keyboard", NULL); | 2876 | value = config_get_string (NULL, CONFIG_KEY_KEYBOARD, NULL); |
1330 | 2933 | a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid"); | 2877 | if (value) |
1331 | 2934 | g_free (value); | 2878 | { |
1332 | 2935 | 2879 | a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid"); | |
1333 | 2880 | g_free (value); | ||
1334 | 2881 | } | ||
1335 | 2936 | gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL); | 2882 | gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL); |
1336 | 2937 | 2883 | ||
1339 | 2938 | value = g_key_file_get_value (config, "greeter", "reader", NULL); | 2884 | |
1340 | 2939 | a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem); | 2885 | |
1341 | 2886 | value = config_get_string (NULL, CONFIG_KEY_READER, NULL); | ||
1342 | 2887 | if (value) | ||
1343 | 2888 | { | ||
1344 | 2889 | a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem); | ||
1345 | 2890 | g_free (value); | ||
1346 | 2891 | } | ||
1347 | 2940 | gtk_widget_set_visible (reader_menuitem, a11y_reader_command != NULL); | 2892 | gtk_widget_set_visible (reader_menuitem, a11y_reader_command != NULL); |
1348 | 2941 | g_free (value); | ||
1349 | 2942 | 2893 | ||
1350 | 2943 | /* Power menu */ | 2894 | /* Power menu */ |
1351 | 2944 | if (gtk_widget_get_visible (power_menuitem)) | 2895 | if (gtk_widget_get_visible (power_menuitem)) |
1352 | @@ -2997,9 +2948,7 @@ | |||
1353 | 2997 | { | 2948 | { |
1354 | 2998 | gtk_menu_item_set_label (GTK_MENU_ITEM (clock_menuitem), ""); | 2949 | gtk_menu_item_set_label (GTK_MENU_ITEM (clock_menuitem), ""); |
1355 | 2999 | clock_label = gtk_bin_get_child (GTK_BIN (clock_menuitem)); | 2950 | clock_label = gtk_bin_get_child (GTK_BIN (clock_menuitem)); |
1359 | 3000 | clock_format = g_key_file_get_value (config, "greeter", "clock-format", NULL); | 2951 | clock_format = config_get_string (NULL, CONFIG_KEY_CLOCK_FORMAT, "%a, %H:%M"); |
1357 | 3001 | if (!clock_format) | ||
1358 | 3002 | clock_format = "%a, %H:%M"; | ||
1360 | 3003 | clock_timeout_thread (); | 2952 | clock_timeout_thread (); |
1361 | 3004 | gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL); | 2953 | gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL); |
1362 | 3005 | } | 2954 | } |
1363 | @@ -3023,49 +2972,21 @@ | |||
1364 | 3023 | /* Background */ | 2972 | /* Background */ |
1365 | 3024 | greeter_background = greeter_background_new (GTK_WIDGET (screen_overlay)); | 2973 | greeter_background = greeter_background_new (GTK_WIDGET (screen_overlay)); |
1366 | 3025 | 2974 | ||
1368 | 3026 | value = g_key_file_get_value (config, "greeter", "active-monitor", NULL); | 2975 | value = config_get_string (NULL, CONFIG_KEY_ACTIVE_MONITOR, NULL); |
1369 | 3027 | greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor"); | 2976 | greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor"); |
1370 | 3028 | g_free (value); | 2977 | g_free (value); |
1371 | 3029 | 2978 | ||
1373 | 3030 | const gchar *CONFIG_MONITOR_PREFIX = "monitor:"; | 2979 | read_monitor_configuration (CONFIG_GROUP_DEFAULT, GREETER_BACKGROUND_DEFAULT); |
1374 | 2980 | |||
1375 | 3031 | gchar **config_group; | 2981 | gchar **config_group; |
1377 | 3032 | gchar **config_groups = g_key_file_get_groups (config, NULL); | 2982 | gchar **config_groups = config_get_groups (CONFIG_GROUP_MONITOR); |
1378 | 3033 | for (config_group = config_groups; *config_group; ++config_group) | 2983 | for (config_group = config_groups; *config_group; ++config_group) |
1379 | 3034 | { | 2984 | { |
1414 | 3035 | gchar *name_to_free = NULL; | 2985 | const gchar *name = *config_group + sizeof (CONFIG_GROUP_MONITOR); |
1415 | 3036 | const gchar *name = *config_group; | 2986 | while (*name && g_ascii_isspace (*name)) |
1416 | 3037 | 2987 | ++name; | |
1417 | 3038 | if (g_strcmp0 (*config_group, "greeter") != 0) | 2988 | |
1418 | 3039 | { | 2989 | read_monitor_configuration (*config_group, name); |
1385 | 3040 | if (!g_str_has_prefix (name, CONFIG_MONITOR_PREFIX)) | ||
1386 | 3041 | continue; | ||
1387 | 3042 | name = *config_group + sizeof (CONFIG_MONITOR_PREFIX); | ||
1388 | 3043 | while (*name && g_ascii_isspace (*name)) | ||
1389 | 3044 | ++name; | ||
1390 | 3045 | } | ||
1391 | 3046 | else | ||
1392 | 3047 | name = name_to_free = g_strdup (GREETER_BACKGROUND_DEFAULT); | ||
1393 | 3048 | |||
1394 | 3049 | g_debug ("Monitor configuration found: '%s'", name); | ||
1395 | 3050 | |||
1396 | 3051 | GError *user_bg_error = NULL, *laptop_error = NULL, *duration_error = NULL; | ||
1397 | 3052 | gboolean user_bg = g_key_file_get_boolean (config, *config_group, "user-background", &user_bg_error); | ||
1398 | 3053 | gboolean laptop = g_key_file_get_boolean (config, *config_group, "laptop", &laptop_error); | ||
1399 | 3054 | gchar *background = g_key_file_get_value (config, *config_group, "background", NULL); | ||
1400 | 3055 | gchar *tr_type = g_key_file_get_string (config, *config_group, "transition-type", NULL); | ||
1401 | 3056 | gint tr_duration = g_key_file_get_integer (config, *config_group, "transition-duration", &duration_error); | ||
1402 | 3057 | |||
1403 | 3058 | greeter_background_set_monitor_config (greeter_background, name, background, | ||
1404 | 3059 | user_bg, user_bg_error == NULL, | ||
1405 | 3060 | laptop, laptop_error == NULL, | ||
1406 | 3061 | duration_error == NULL ? tr_duration : -1, | ||
1407 | 3062 | tr_type); | ||
1408 | 3063 | |||
1409 | 3064 | g_free (tr_type); | ||
1410 | 3065 | g_free (background); | ||
1411 | 3066 | g_free (name_to_free); | ||
1412 | 3067 | g_clear_error (&user_bg_error); | ||
1413 | 3068 | g_clear_error (&laptop_error); | ||
1419 | 3069 | } | 2990 | } |
1420 | 3070 | g_strfreev (config_groups); | 2991 | g_strfreev (config_groups); |
1421 | 3071 | 2992 | ||
1422 | @@ -3087,22 +3008,26 @@ | |||
1423 | 3087 | } | 3008 | } |
1424 | 3088 | 3009 | ||
1425 | 3089 | /* Windows positions */ | 3010 | /* Windows positions */ |
1432 | 3090 | g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION, | 3011 | value = config_get_string (NULL, CONFIG_KEY_POSITION, NULL); |
1433 | 3091 | key_file_get_position (config, "greeter", "position", &WINDOW_POS_CENTER), g_free); | 3012 | g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION, str_to_position (value, &WINDOW_POS_CENTER), g_free); |
1428 | 3092 | |||
1429 | 3093 | value = g_key_file_get_value (config, "greeter", "panel-position", NULL); | ||
1430 | 3094 | if (g_strcmp0 (value, "bottom") == 0) | ||
1431 | 3095 | gtk_widget_set_valign (panel_window, GTK_ALIGN_END); | ||
1434 | 3096 | g_free (value); | 3013 | g_free (value); |
1435 | 3097 | 3014 | ||
1436 | 3015 | |||
1437 | 3016 | gtk_widget_set_valign (panel_window, config_get_enum (NULL, CONFIG_KEY_PANEL_POSITION, GTK_ALIGN_START, | ||
1438 | 3017 | "bottom", GTK_ALIGN_END, | ||
1439 | 3018 | "top", GTK_ALIGN_START, NULL)); | ||
1440 | 3019 | |||
1441 | 3098 | if (a11y_keyboard_command) | 3020 | if (a11y_keyboard_command) |
1444 | 3099 | g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION, | 3021 | { |
1445 | 3100 | key_file_get_position (config, "greeter", "keyboard-position", &KEYBOARD_POSITION), g_free); | 3022 | value = config_get_string (NULL, CONFIG_KEY_KEYBOARD_POSITION, NULL); |
1446 | 3023 | g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION, str_to_position (value, &KEYBOARD_POSITION), g_free); | ||
1447 | 3024 | g_free (value); | ||
1448 | 3025 | } | ||
1449 | 3101 | 3026 | ||
1450 | 3102 | gtk_builder_connect_signals (builder, greeter); | 3027 | gtk_builder_connect_signals (builder, greeter); |
1451 | 3103 | 3028 | ||
1454 | 3104 | values = g_key_file_get_string_list (config, "greeter", "a11y-states", NULL, NULL); | 3029 | gchar **a11y_states = config_get_string_list (NULL, CONFIG_KEY_A11Y_STATES, NULL); |
1455 | 3105 | if (values && *values) | 3030 | if (a11y_states && *a11y_states) |
1456 | 3106 | { | 3031 | { |
1457 | 3107 | GHashTable *items = g_hash_table_new (g_str_hash, g_str_equal); | 3032 | GHashTable *items = g_hash_table_new (g_str_hash, g_str_equal); |
1458 | 3108 | g_hash_table_insert (items, "contrast", contrast_menuitem); | 3033 | g_hash_table_insert (items, "contrast", contrast_menuitem); |
1459 | @@ -3112,7 +3037,7 @@ | |||
1460 | 3112 | 3037 | ||
1461 | 3113 | gpointer item; | 3038 | gpointer item; |
1462 | 3114 | gchar **values_iter; | 3039 | gchar **values_iter; |
1464 | 3115 | for (values_iter = values; *values_iter; ++values_iter) | 3040 | for (values_iter = a11y_states; *values_iter; ++values_iter) |
1465 | 3116 | { | 3041 | { |
1466 | 3117 | value = *values_iter; | 3042 | value = *values_iter; |
1467 | 3118 | switch (value[0]) | 3043 | switch (value[0]) |
1468 | @@ -3131,19 +3056,19 @@ | |||
1469 | 3131 | gtk_widget_get_visible (GTK_WIDGET (item))) | 3056 | gtk_widget_get_visible (GTK_WIDGET (item))) |
1470 | 3132 | { | 3057 | { |
1471 | 3133 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), | 3058 | gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), |
1473 | 3134 | g_key_file_get_boolean (state, "a11y-states", value, NULL)); | 3059 | config_get_bool (STATE_SECTION_A11Y, value, FALSE)); |
1474 | 3135 | g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (a11y_menuitem_toggled_cb), g_strdup (value)); | 3060 | g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (a11y_menuitem_toggled_cb), g_strdup (value)); |
1475 | 3136 | } | 3061 | } |
1476 | 3137 | } | 3062 | } |
1477 | 3138 | } | 3063 | } |
1478 | 3139 | g_hash_table_unref (items); | 3064 | g_hash_table_unref (items); |
1479 | 3140 | } | 3065 | } |
1481 | 3141 | g_strfreev (values); | 3066 | g_strfreev (a11y_states); |
1482 | 3142 | 3067 | ||
1484 | 3143 | /* focus fix (source: unity-greeter) */ | 3068 | /* There is no window manager, so we need to implement some of its functionality */ |
1485 | 3144 | GdkWindow* root_window = gdk_get_default_root_window (); | 3069 | GdkWindow* root_window = gdk_get_default_root_window (); |
1486 | 3145 | gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK); | 3070 | gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK); |
1488 | 3146 | gdk_window_add_filter (root_window, focus_upon_map, NULL); | 3071 | gdk_window_add_filter (root_window, wm_window_filter, NULL); |
1489 | 3147 | 3072 | ||
1490 | 3148 | gtk_widget_show (GTK_WIDGET (screen_overlay)); | 3073 | gtk_widget_show (GTK_WIDGET (screen_overlay)); |
1491 | 3149 | 3074 | ||
1492 | 3150 | 3075 | ||
1493 | === modified file 'src/lightdm-gtk-greeter.glade' | |||
1494 | --- src/lightdm-gtk-greeter.glade 2014-12-10 07:59:02 +0000 | |||
1495 | +++ src/lightdm-gtk-greeter.glade 2015-03-29 05:44:39 +0000 | |||
1496 | @@ -282,6 +282,7 @@ | |||
1497 | 282 | <property name="name">cancel_button</property> | 282 | <property name="name">cancel_button</property> |
1498 | 283 | <property name="visible">True</property> | 283 | <property name="visible">True</property> |
1499 | 284 | <property name="can_focus">True</property> | 284 | <property name="can_focus">True</property> |
1500 | 285 | <property name="receives_default">False</property> | ||
1501 | 285 | <signal name="clicked" handler="power_button_clicked_cb" swapped="no"/> | 286 | <signal name="clicked" handler="power_button_clicked_cb" swapped="no"/> |
1502 | 286 | </object> | 287 | </object> |
1503 | 287 | <packing> | 288 | <packing> |
1504 | @@ -296,6 +297,7 @@ | |||
1505 | 296 | <property name="name">power_ok_button</property> | 297 | <property name="name">power_ok_button</property> |
1506 | 297 | <property name="visible">True</property> | 298 | <property name="visible">True</property> |
1507 | 298 | <property name="can_focus">True</property> | 299 | <property name="can_focus">True</property> |
1508 | 300 | <property name="receives_default">False</property> | ||
1509 | 299 | <signal name="clicked" handler="power_button_clicked_cb" swapped="no"/> | 301 | <signal name="clicked" handler="power_button_clicked_cb" swapped="no"/> |
1510 | 300 | </object> | 302 | </object> |
1511 | 301 | <packing> | 303 | <packing> |
1512 | @@ -326,10 +328,9 @@ | |||
1513 | 326 | <property name="vexpand">True</property> | 328 | <property name="vexpand">True</property> |
1514 | 327 | <signal name="get-child-position" handler="screen_overlay_get_child_position_cb" swapped="no"/> | 329 | <signal name="get-child-position" handler="screen_overlay_get_child_position_cb" swapped="no"/> |
1515 | 328 | <child> | 330 | <child> |
1517 | 329 | <object class="GtkBox" id="screen-child"> | 331 | <object class="GtkEventBox" id="screen_overlay_child"> |
1518 | 330 | <property name="visible">True</property> | 332 | <property name="visible">True</property> |
1519 | 331 | <property name="can_focus">False</property> | 333 | <property name="can_focus">False</property> |
1520 | 332 | <property name="orientation">vertical</property> | ||
1521 | 333 | <child> | 334 | <child> |
1522 | 334 | <placeholder/> | 335 | <placeholder/> |
1523 | 335 | </child> | 336 | </child> |
1524 | @@ -541,6 +542,7 @@ | |||
1525 | 541 | <property name="name">cancel_button</property> | 542 | <property name="name">cancel_button</property> |
1526 | 542 | <property name="visible">True</property> | 543 | <property name="visible">True</property> |
1527 | 543 | <property name="can_focus">True</property> | 544 | <property name="can_focus">True</property> |
1528 | 545 | <property name="receives_default">False</property> | ||
1529 | 544 | <signal name="clicked" handler="cancel_cb" swapped="no"/> | 546 | <signal name="clicked" handler="cancel_cb" swapped="no"/> |
1530 | 545 | </object> | 547 | </object> |
1531 | 546 | <packing> | 548 | <packing> |
1532 | @@ -555,6 +557,7 @@ | |||
1533 | 555 | <property name="name">login_button</property> | 557 | <property name="name">login_button</property> |
1534 | 556 | <property name="visible">True</property> | 558 | <property name="visible">True</property> |
1535 | 557 | <property name="can_focus">True</property> | 559 | <property name="can_focus">True</property> |
1536 | 560 | <property name="receives_default">False</property> | ||
1537 | 558 | <signal name="clicked" handler="login_cb" swapped="no"/> | 561 | <signal name="clicked" handler="login_cb" swapped="no"/> |
1538 | 559 | </object> | 562 | </object> |
1539 | 560 | <packing> | 563 | <packing> |
Hey Andrew!
This is a huge amount of changes so I guess the branch-name is accurate :)
I wonder whether we could rip out some parts of it as bugfix for 2.0 and then do a bugfix release for it which we could then still upload to 15.04. Would that be possible?