summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/greeterbackground.c85
-rw-r--r--src/lightdm-gtk-greeter-fallback.css10
-rw-r--r--src/lightdm-gtk-greeter.c67
-rw-r--r--src/lightdm-gtk-greeter.glade7
4 files changed, 102 insertions, 67 deletions
diff --git a/src/greeterbackground.c b/src/greeterbackground.c
index 4487644..a4105dd 100644
--- a/src/greeterbackground.c
+++ b/src/greeterbackground.c
@@ -58,7 +58,7 @@ typedef struct
} BackgroundConfig;
/* Transition configuration
- Used to as part of <MonitorConfig> and <Monitor> */
+ Used as part of <MonitorConfig> and <Monitor> */
typedef struct
{
/* Transition duration, in ms */
@@ -177,9 +177,6 @@ struct _GreeterBackgroundPrivate
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_root_pixmap_id (GdkScreen* screen,
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 @@ static const MonitorConfig DEFAULT_MONITOR_CONFIG =
.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 @@ greeter_background_set_monitor_config(GreeterBackground* background,
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 @@ greeter_background_connect(GreeterBackground* background,
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 @@ greeter_background_connect(GreeterBackground* background,
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 @@ greeter_background_connect(GreeterBackground* background,
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 @@ greeter_background_connect(GreeterBackground* background,
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 @@ greeter_background_connect(GreeterBackground* background,
}
}
}
+
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);
@@ -1393,8 +1412,30 @@ monitor_window_enter_notify_cb(GtkWidget* widget,
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 +1674,7 @@ transition_func_linear(gdouble x)
}
static gdouble
-transition_func_easy_in_out(gdouble x)
+transition_func_ease_in_out(gdouble x)
{
return (1 - cos(M_PI*x))/2;
}
diff --git a/src/lightdm-gtk-greeter-fallback.css b/src/lightdm-gtk-greeter-fallback.css
index f98064b..1d28490 100644
--- a/src/lightdm-gtk-greeter-fallback.css
+++ b/src/lightdm-gtk-greeter-fallback.css
@@ -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;
}
diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c
index 69627ab..7a08a44 100644
--- a/src/lightdm-gtk-greeter.c
+++ b/src/lightdm-gtk-greeter.c
@@ -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 close_pid (GPid pid, gboolean remove);
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_contrast_cb (GtkCheckMenuItem *item);
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 @@ greeter_save_focus(GtkWidget* widget)
void
greeter_restore_focus(const gpointer saved_data)
{
- if (!saved_data)
+ struct SavedFocusData *data = saved_data;
+
+ if (!saved_data || !GTK_IS_WIDGET (data->widget))
return;
- struct SavedFocusData *data = saved_data;
- if (GTK_IS_WIDGET (data->widget))
- gtk_widget_grab_focus (data->widget);
+ 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 @@ set_user_image (const gchar *username)
}
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 @@ menu_command_run (MenuCommand *command)
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 @@ menu_command_run (MenuCommand *command)
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 @@ load_user_list (void)
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;
- XGetInputFocus (xevent->xunmap.display, &xwin, &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 @@ main (int argc, char **argv)
/* 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 @@ main (int argc, char **argv)
}
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));
diff --git a/src/lightdm-gtk-greeter.glade b/src/lightdm-gtk-greeter.glade
index 1230d2e..11fb826 100644
--- a/src/lightdm-gtk-greeter.glade
+++ b/src/lightdm-gtk-greeter.glade
@@ -282,6 +282,7 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -296,6 +297,7 @@
<property name="name">power_ok_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -326,10 +328,9 @@
<property name="vexpand">True</property>
<signal name="get-child-position" handler="screen_overlay_get_child_position_cb" swapped="no"/>
<child>
- <object class="GtkBox" id="screen-child">
+ <object class="GtkEventBox" id="screen_overlay_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
@@ -541,6 +542,7 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="cancel_cb" swapped="no"/>
</object>
<packing>
@@ -555,6 +557,7 @@
<property name="name">login_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="login_cb" swapped="no"/>
</object>
<packing>