diff --git a/src/Makefile.am b/src/Makefile.am index 4c4ed3e2..457f90f1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,6 +111,8 @@ test_watcher_LDADD = \ test_window_SOURCES = \ test-window.c \ + gs-lock-socket.c \ + gs-lock-socket.h \ gs-window.h \ gs-window-x11.c \ gs-grab-x11.c \ @@ -172,6 +174,8 @@ cinnamon_screensaver_SOURCES = \ gs-watcher.h \ gs-listener-dbus.c \ gs-listener-dbus.h \ + gs-lock-socket.c \ + gs-lock-socket.h \ gs-manager.c \ gs-manager.h \ gs-window-x11.c \ diff --git a/src/gs-lock-socket.c b/src/gs-lock-socket.c new file mode 100644 index 00000000..56de201d --- /dev/null +++ b/src/gs-lock-socket.c @@ -0,0 +1,140 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. + * + */ + +#include "config.h" +#include "gs-lock-socket.h" +#include "string.h" +#include + +static void gs_lock_socket_class_init (GSLockSocketClass *klass); +static void gs_lock_socket_init (GSLockSocket *window); + +G_DEFINE_TYPE (GSLockSocket, gs_lock_socket, GTK_TYPE_SOCKET) + +static void +gs_lock_socket_send_configure_event (GSLockSocket *lock_socket) +{ + GtkAllocation allocation; + XConfigureEvent xconfigure; + gint x, y; + + GtkSocket *socket = GTK_SOCKET (lock_socket); + + GdkWindow *window = gtk_socket_get_plug_window (socket); + + g_return_if_fail (window != NULL); + + memset (&xconfigure, 0, sizeof (xconfigure)); + xconfigure.type = ConfigureNotify; + + xconfigure.event = GDK_WINDOW_XID (window); + xconfigure.window = GDK_WINDOW_XID (window); + + /* The ICCCM says that synthetic events should have root relative + * coordinates. We still aren't really ICCCM compliant, since + * we don't send events when the real toplevel is moved. + */ + gdk_error_trap_push (); + gdk_window_get_origin (window, &x, &y); + gdk_error_trap_pop_ignored (); + + gtk_widget_get_allocation (GTK_WIDGET(socket), &allocation); + gint scale = gtk_widget_get_scale_factor (GTK_WIDGET (socket)); + xconfigure.x = x; + xconfigure.y = y; + xconfigure.width = allocation.width * scale; + xconfigure.height = allocation.height * scale; + + xconfigure.border_width = 0; + xconfigure.above = None; + xconfigure.override_redirect = False; + + gdk_error_trap_push (); + XSendEvent (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + False, NoEventMask, (XEvent *)&xconfigure); + gdk_error_trap_pop_ignored (); +} + +static void +gs_lock_socket_get_preferred_height (GtkWidget *widget, + gint *min_size, + gint *natural_size) +{ + GTK_WIDGET_CLASS (gs_lock_socket_parent_class)->get_preferred_height (widget, + min_size, + natural_size); + + gint scale = gtk_widget_get_scale_factor (widget); + *min_size = *min_size / scale; + *natural_size = *natural_size / scale; +} + +static void +gs_lock_socket_get_preferred_width (GtkWidget *widget, + gint *min_size, + gint *natural_size) +{ + GTK_WIDGET_CLASS (gs_lock_socket_parent_class)->get_preferred_width (widget, + min_size, + natural_size); + + gint scale = gtk_widget_get_scale_factor (widget); + *min_size = *min_size / scale; + *natural_size = *natural_size / scale; +} + +static void +gs_lock_socket_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GSLockSocket *socket = GS_LOCK_SOCKET (widget); + + gs_lock_socket_send_configure_event (socket); + + GTK_WIDGET_CLASS (gs_lock_socket_parent_class)->size_allocate (widget, + allocation); + gs_lock_socket_send_configure_event (socket); +} + +static void +gs_lock_socket_class_init (GSLockSocketClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->size_allocate = gs_lock_socket_size_allocate; + widget_class->get_preferred_height = gs_lock_socket_get_preferred_height; + widget_class->get_preferred_width = gs_lock_socket_get_preferred_width; +} + +static void +gs_lock_socket_init (GSLockSocket *window) +{ +} + +GSLockSocket * +gs_lock_socket_new (void) +{ + GObject *result; + + result = g_object_new (GS_TYPE_LOCK_SOCKET, + NULL); + + return GS_LOCK_SOCKET (result); +} diff --git a/src/gs-lock-socket.h b/src/gs-lock-socket.h new file mode 100644 index 00000000..6489c3f1 --- /dev/null +++ b/src/gs-lock-socket.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. + * + */ + +#ifndef __GS_LOCK_SOCKET_H +#define __GS_LOCK_SOCKET_H + +#include +#include + +G_BEGIN_DECLS + +#define GS_TYPE_LOCK_SOCKET (gs_lock_socket_get_type ()) +#define GS_LOCK_SOCKET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_LOCK_SOCKET, GSLockSocket)) +#define GS_LOCK_SOCKET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_LOCK_SOCKET, GSLockSocketClass)) +#define GS_IS_LOCK_SOCKET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_LOCK_SOCKET)) +#define GS_IS_LOCK_SOCKET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_LOCK_SOCKET)) +#define GS_LOCK_SOCKET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_LOCK_SOCKET, GSLockSocketClass)) + +typedef struct +{ + GtkSocket socket; +} GSLockSocket; + +typedef struct +{ + GtkSocketClass socket_class; +} GSLockSocketClass; + +GType gs_lock_socket_get_type (void); + +GSLockSocket * gs_lock_socket_new (void); + +G_END_DECLS + +#endif /* __GS_LOCK_SOCKET_H */ diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c index 56f50555..e0ae0c0f 100644 --- a/src/gs-window-x11.c +++ b/src/gs-window-x11.c @@ -34,6 +34,7 @@ #include "gnome-wall-clock.h" +#include "gs-lock-socket.h" #include "gs-window.h" #include "gs-marshal.h" #include "subprocs.h" @@ -1339,7 +1340,7 @@ static void create_lock_socket (GSWindow *window, guint32 id) { - window->priv->lock_socket = gtk_socket_new (); + window->priv->lock_socket = gs_lock_socket_new (); window->priv->lock_box = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_widget_show (window->priv->lock_box);