From 8e6328fc992c9335dcb79f95399cb20766724048 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 5 Mar 2015 15:46:51 +0100 Subject: [PATCH 1/1] lightdm-gtk-greeter: fix FS#43999 --- PKGBUILD | 15 +- post-2.0.patch | 428 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 440 insertions(+), 3 deletions(-) create mode 100644 post-2.0.patch diff --git a/PKGBUILD b/PKGBUILD index 174372b..5698aba 100755 --- a/PKGBUILD +++ b/PKGBUILD @@ -4,7 +4,7 @@ pkgname=lightdm-gtk-greeter pkgver=2.0.0 -pkgrel=1 +pkgrel=2 epoch=1 pkgdesc='GTK+ greeter for LightDM' arch=('i686' 'x86_64') @@ -16,8 +16,17 @@ makedepends=('gnome-common' 'gnome-doc-utils' 'gobject-introspection' replaces=('lightdm-gtk3-greeter') backup=('etc/lightdm/lightdm-gtk-greeter.conf') install='lightdm-gtk-greeter.install' -source=("https://launchpad.net/lightdm-gtk-greeter/${pkgver%.?}/${pkgver}/+download/lightdm-gtk-greeter-${pkgver}.tar.gz") -sha256sums=('4c0a0121d1ec82c85c8aed4ad80ebd48ddc56d9bace31da72423bfd330c26484') +source=("https://launchpad.net/lightdm-gtk-greeter/${pkgver%.?}/${pkgver}/+download/lightdm-gtk-greeter-${pkgver}.tar.gz" + post-2.0.patch) +sha256sums=('4c0a0121d1ec82c85c8aed4ad80ebd48ddc56d9bace31da72423bfd330c26484' + 'a3c07a97fe774931f48e8b6a6da449dcf891abd3caae61711be074bdb773d9ea') + +prepare() { + cd lightdm-gtk-greeter-${pkgver} + + # fix FS#43999 + patch -Np0 < "${srcdir}/post-2.0.patch" +} build() { cd lightdm-gtk-greeter-${pkgver} diff --git a/post-2.0.patch b/post-2.0.patch new file mode 100644 index 0000000..27d0453 --- /dev/null +++ b/post-2.0.patch @@ -0,0 +1,428 @@ +=== modified file 'src/greeterbackground.c' +--- src/greeterbackground.c 2014-12-10 07:59:02 +0000 ++++ src/greeterbackground.c 2015-03-04 07:33:32 +0000 +@@ -58,7 +58,7 @@ + } BackgroundConfig; + + /* Transition configuration +- Used to as part of and */ ++ Used as part of and */ + typedef struct + { + /* Transition duration, in ms */ +@@ -177,9 +177,6 @@ + gboolean follow_cursor; + /* Use cursor position to determinate initial active monitor */ + gboolean follow_cursor_to_init; +- +- /* Name => transition function, inited in set_monitor_config() */ +- GHashTable* transition_types; + }; + + enum +@@ -296,7 +293,7 @@ + static void set_surface_as_root (GdkScreen* screen, + cairo_surface_t* surface); + static gdouble transition_func_linear (gdouble x); +-static gdouble transition_func_easy_in_out (gdouble x); ++static gdouble transition_func_ease_in_out (gdouble x); + + /* Implemented in lightdm-gtk-greeter.c */ + gpointer greeter_save_focus(GtkWidget* widget); +@@ -317,7 +314,7 @@ + .transition = + { + .duration = 500, +- .func = transition_func_easy_in_out, ++ .func = transition_func_ease_in_out, + .draw = (TransitionDraw)monitor_transition_draw_alpha + } + }; +@@ -434,14 +431,13 @@ + + if(transition_type) + { +- if(!priv->transition_types) +- { +- priv->transition_types = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); +- g_hash_table_insert(priv->transition_types, g_strdup("none"), NULL); +- g_hash_table_insert(priv->transition_types, g_strdup("linear"), transition_func_linear); +- g_hash_table_insert(priv->transition_types, g_strdup("easy-in-out"), transition_func_easy_in_out); +- } +- if(!g_hash_table_lookup_extended(priv->transition_types, transition_type, NULL, (gpointer*)&config->transition.func)) ++ if(g_strcmp0(transition_type, "none") == 0) ++ config->transition.func = NULL; ++ else if(g_strcmp0(transition_type, "ease-in-out") == 0) ++ config->transition.func = transition_func_ease_in_out; ++ else if(g_strcmp0(transition_type, "linear") == 0) ++ config->transition.func = transition_func_linear; ++ else + { + g_warning("[Background] Invalid transition type for '%s' monitor: '%s'. Using fallback value.", + name, transition_type); +@@ -495,12 +491,18 @@ + g_return_if_fail(GREETER_IS_BACKGROUND(background)); + g_return_if_fail(GDK_IS_SCREEN(screen)); + +- g_debug("[Background] Connecting to screen: %p", screen); ++ g_debug("[Background] Connecting to screen: %p (%dx%dpx, %dx%dmm)", screen, ++ gdk_screen_get_width(screen), gdk_screen_get_height(screen), ++ gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm(screen)); + + GreeterBackgroundPrivate* priv = background->priv; +- ++ gpointer saved_focus = NULL; + if(priv->screen) ++ { ++ if (priv->active_monitor) ++ saved_focus = greeter_save_focus(priv->child); + greeter_background_disconnect(background); ++ } + + priv->screen = screen; + priv->monitors_size = gdk_screen_get_n_monitors(screen); +@@ -513,7 +515,9 @@ + Monitor* first_not_skipped_monitor = NULL; + + GHashTable* images_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); ++ cairo_region_t *screen_region = cairo_region_create(); + gint i; ++ + for(i = 0; i < priv->monitors_size; ++i) + { + const MonitorConfig* config; +@@ -553,6 +557,15 @@ + config = &DEFAULT_MONITOR_CONFIG; + } + ++ /* Simple check to skip fully overlapped monitors. ++ Actually, it's can track only monitors in "mirrors" mode. Nothing more. */ ++ if(cairo_region_contains_rectangle(screen_region, &monitor->geometry) == CAIRO_REGION_OVERLAP_IN) ++ { ++ g_debug("[Background] Skipping monitor %s #%d, its area is already used by other monitors", printable_name, i); ++ continue; ++ } ++ cairo_region_union_rectangle(screen_region, &monitor->geometry); ++ + if(!first_not_skipped_monitor) + first_not_skipped_monitor = monitor; + +@@ -578,9 +591,8 @@ + for(item = priv->accel_groups; item != NULL; item = g_slist_next(item)) + gtk_window_add_accel_group(monitor->window, item->data); + +- if(priv->follow_cursor) +- g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event", +- G_CALLBACK(monitor_window_enter_notify_cb), monitor); ++ g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event", ++ G_CALLBACK(monitor_window_enter_notify_cb), monitor); + + if(config->user_bg) + priv->customized_monitors = g_slist_prepend(priv->customized_monitors, monitor); +@@ -624,9 +636,16 @@ + } + } + } ++ + if(!priv->active_monitor) + greeter_background_set_active_monitor(background, NULL); + ++ if(saved_focus) ++ { ++ greeter_restore_focus(saved_focus); ++ g_free(saved_focus); ++ } ++ + priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed", + G_CALLBACK(greeter_background_monitors_changed_cb), + background); +@@ -768,8 +787,9 @@ + gpointer focus = greeter_save_focus(priv->child); + + if(old_parent) +- gtk_container_remove(GTK_CONTAINER(old_parent), priv->child); +- gtk_container_add(GTK_CONTAINER(active->window), priv->child); ++ gtk_widget_reparent(priv->child, GTK_WIDGET(active->window)); ++ else ++ gtk_container_add(GTK_CONTAINER(active->window), priv->child); + + gtk_window_present(active->window); + greeter_restore_focus(focus); +@@ -1393,8 +1413,30 @@ + GdkEventCrossing* event, + const Monitor* monitor) + { +- if(monitor->object->priv->active_monitor != monitor && +- greeter_background_monitor_enabled(monitor->object, monitor)) ++ if(monitor->object->priv->active_monitor == monitor) ++ { ++ GdkWindow *gdkwindow = gtk_widget_get_window (widget); ++ Window window = GDK_WINDOW_XID (gdkwindow); ++ Display *display = GDK_WINDOW_XDISPLAY (gdkwindow); ++ ++ static Atom wm_protocols = None; ++ static Atom wm_take_focus = None; ++ ++ if (!wm_protocols) ++ wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); ++ if (!wm_take_focus) ++ wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False); ++ ++ XEvent ev = {0}; ++ ev.xclient.type = ClientMessage; ++ ev.xclient.window = window; ++ ev.xclient.message_type = wm_protocols; ++ ev.xclient.format = 32; ++ ev.xclient.data.l[0] = wm_take_focus; ++ ev.xclient.data.l[1] = CurrentTime; ++ XSendEvent(display, window, False, 0L, &ev); ++ } ++ else if(monitor->object->priv->follow_cursor && greeter_background_monitor_enabled(monitor->object, monitor)) + greeter_background_set_active_monitor(monitor->object, monitor); + return FALSE; + } +@@ -1633,7 +1675,7 @@ + } + + static gdouble +-transition_func_easy_in_out(gdouble x) ++transition_func_ease_in_out(gdouble x) + { + return (1 - cos(M_PI*x))/2; + } + +=== modified file 'src/lightdm-gtk-greeter-fallback.css' +--- src/lightdm-gtk-greeter-fallback.css 2014-05-22 19:52:34 +0000 ++++ src/lightdm-gtk-greeter-fallback.css 2015-03-04 07:33:32 +0000 +@@ -1,12 +1,12 @@ + #layout_menuitem>GtkLabel + { +- border: 1px solid alpha(@menu_fg_color, 0.8); +- border-radius: 0.5em; +- padding: 0px 0.25em; +- background: alpha(@menu_fg_color, 0.2); ++ border: 1px solid alpha(@menu_fg_color, 0.8); ++ border-radius: 0.5em; ++ padding: 0px 0.25em; ++ background: alpha(@menu_fg_color, 0.2); + } + + #layout_menuitem + { +- padding: 1px; ++ padding: 1px; + } + +=== modified file 'src/lightdm-gtk-greeter.c' +--- src/lightdm-gtk-greeter.c 2015-01-26 14:41:10 +0000 ++++ src/lightdm-gtk-greeter.c 2015-03-04 07:33:32 +0000 +@@ -53,6 +53,7 @@ + #include "src/lightdm-gtk-greeter-css-fallback.h" + #include "src/lightdm-gtk-greeter-css-application.h" + ++ + static LightDMGreeter *greeter; + + /* State file */ +@@ -70,7 +71,8 @@ + static void sigterm_cb (gpointer user_data); + + /* Screen window */ +-static GtkOverlay *screen_overlay; ++static GtkOverlay *screen_overlay; ++static GtkWidget *screen_overlay_child; + + /* Login window */ + static GtkWidget *login_window; +@@ -283,7 +285,7 @@ + void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data); + void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data); + +-/* Power indciator */ ++/* Power indicator */ + static void power_menu_cb (GtkWidget *menuitem, gpointer userdata); + void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter); + void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter); +@@ -316,12 +318,12 @@ + void + greeter_restore_focus(const gpointer saved_data) + { +- if (!saved_data) +- return; +- + struct SavedFocusData *data = saved_data; +- if (GTK_IS_WIDGET (data->widget)) +- gtk_widget_grab_focus (data->widget); ++ ++ if (!saved_data || !GTK_IS_WIDGET (data->widget)) ++ return; ++ ++ gtk_widget_grab_focus (data->widget); + if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1) + gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos); + } +@@ -732,7 +734,7 @@ + } + else + { +- g_warning ("Failed to load user image: %s", error->message); ++ g_debug ("Failed to load user image: %s", error->message); + g_clear_error (&error); + } + } +@@ -849,6 +851,7 @@ + if (id != 0 && end_ptr > text) + { + socket = GTK_SOCKET (gtk_socket_new ()); ++ gtk_container_foreach (GTK_CONTAINER (command->widget), (GtkCallback)gtk_widget_destroy, NULL); + gtk_container_add (GTK_CONTAINER (command->widget), GTK_WIDGET (socket)); + gtk_socket_add_id (socket, id); + gtk_widget_show_all (GTK_WIDGET (command->widget)); +@@ -879,6 +882,7 @@ + g_warning ("[Command/%s] Failed to run: %s", command->name, error->message); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE); + } ++ + g_clear_error (&error); + + return command->pid; +@@ -2513,54 +2517,40 @@ + set_displayed_user (greeter, name); + g_free (name); + } +- + } + + g_free (last_user); + } + + static GdkFilterReturn +-focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data) ++wm_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data) + { +- XEvent* xevent = (XEvent*)gxevent; +- GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ? +- gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL; ++ XEvent *xevent = (XEvent*)gxevent; + if (xevent->type == MapNotify) + { +- Window xwin = xevent->xmap.window; +- Window keyboard_xid = 0; +- GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display); +- GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin); ++ GdkDisplay *display = gdk_x11_lookup_xdisplay (xevent->xmap.display); ++ GdkWindow *win = gdk_x11_window_foreign_new_for_display (display, xevent->xmap.window); + GdkWindowTypeHint win_type = gdk_window_get_type_hint (win); + +- /* Check to see if this window is our onboard window, since we don't want to focus it. */ +- if (keyboard_win) +- keyboard_xid = gdk_x11_window_get_xid (keyboard_win); +- +- if (xwin != keyboard_xid +- && win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP +- && win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION) +- { ++ if (win_type != GDK_WINDOW_TYPE_HINT_COMBO && ++ win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP && ++ win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION) ++ /* ++ if (win_type == GDK_WINDOW_TYPE_HINT_DESKTOP || ++ win_type == GDK_WINDOW_TYPE_HINT_DIALOG) ++ */ + gdk_window_focus (win, GDK_CURRENT_TIME); +- /* Make sure to keep keyboard above */ +- if (keyboard_win) +- gdk_window_raise (keyboard_win); +- } + } + else if (xevent->type == UnmapNotify) + { + Window xwin; +- int revert_to; ++ int revert_to = RevertToNone; ++ + XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to); +- + if (revert_to == RevertToNone) +- { +- gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME); +- /* Make sure to keep keyboard above */ +- if (keyboard_win) +- gdk_window_raise (keyboard_win); +- } ++ gdk_window_lower (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay)))); + } ++ + return GDK_FILTER_CONTINUE; + } + +@@ -2769,6 +2759,7 @@ + + /* Screen window */ + screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay")); ++ screen_overlay_child = GTK_WIDGET (gtk_builder_get_object (builder, "screen_overlay_child")); + + /* Login window */ + login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window")); +@@ -3140,10 +3131,10 @@ + } + g_strfreev (values); + +- /* focus fix (source: unity-greeter) */ ++ /* There is no window manager, so we need to implement some of its functionality */ + GdkWindow* root_window = gdk_get_default_root_window (); + gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK); +- gdk_window_add_filter (root_window, focus_upon_map, NULL); ++ gdk_window_add_filter (root_window, wm_window_filter, NULL); + + gtk_widget_show (GTK_WIDGET (screen_overlay)); + + +=== modified file 'src/lightdm-gtk-greeter.glade' +--- src/lightdm-gtk-greeter.glade 2014-12-10 07:59:02 +0000 ++++ src/lightdm-gtk-greeter.glade 2015-03-04 07:33:32 +0000 +@@ -282,6 +282,7 @@ + cancel_button + True + True ++ False + + + +@@ -296,6 +297,7 @@ + power_ok_button + True + True ++ False + + + +@@ -326,10 +328,9 @@ + True + + +- ++ + True + False +- vertical + + + +@@ -541,6 +542,7 @@ + cancel_button + True + True ++ False + + + +@@ -555,6 +557,7 @@ + login_button + True + True ++ False + + + + -- 2.3.1