summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2009-12-19 01:23:58 -0500
committerMatthias Clasen <mclasen@redhat.com>2009-12-19 01:23:58 -0500
commit56edab35539fa81b8061dc7e963905b625bc2583 (patch)
treeecbf7e8de2bd707aa1d74044a77e2440ca957cbf
parent9a480910649878c50e4eb6b5f57707118c54505c (diff)
downloadgdk-pixbuf-56edab35539fa81b8061dc7e963905b625bc2583.tar.gz
Implement extended layout for plug/socket
-rw-r--r--gtk/gtkplug-x11.c27
-rw-r--r--gtk/gtkplug.c8
-rw-r--r--gtk/gtkplugprivate.h3
-rw-r--r--gtk/gtksocket-x11.c62
-rw-r--r--gtk/gtksocket.c72
-rw-r--r--gtk/gtksocketprivate.h4
6 files changed, 175 insertions, 1 deletions
diff --git a/gtk/gtkplug-x11.c b/gtk/gtkplug-x11.c
index 95dcf1ab6..fa81b61b5 100644
--- a/gtk/gtkplug-x11.c
+++ b/gtk/gtkplug-x11.c
@@ -32,6 +32,7 @@
#include "gtkplugprivate.h"
#include "x11/gdkx.h"
+#include <X11/Xatom.h>
#include "gtkxembed.h"
#include "gtkalias.h"
@@ -330,3 +331,29 @@ _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
return return_val;
}
+
+void
+_gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
+ GtkRequisition *requisition)
+{
+ GtkWidget *widget = GTK_WIDGET (plug);
+ GdkDisplay *display;
+ GdkWindow *window;
+ gint32 data[2];
+ Atom property;
+
+ gtk_widget_realize (widget);
+
+ window = GTK_WIDGET (plug)->window;
+ display = gdk_drawable_get_display (window);
+ property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
+
+ data[0] = requisition->width;
+ data[1] = requisition->height;
+
+ XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (window), property,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char*)data, 2);
+}
+
diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c
index 4c31ea70d..593df8c1d 100644
--- a/gtk/gtkplug.c
+++ b/gtk/gtkplug.c
@@ -30,6 +30,7 @@
#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkplug.h"
+#include "gtkextendedlayout.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkplugprivate.h"
@@ -721,6 +722,9 @@ static void
gtk_plug_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
+ GtkBin *bin = GTK_BIN (widget);
+ GtkRequisition natural_size;
+
if (GTK_WIDGET_TOPLEVEL (widget))
GTK_WIDGET_CLASS (gtk_plug_parent_class)->size_allocate (widget, allocation);
else
@@ -748,6 +752,10 @@ gtk_plug_size_allocate (GtkWidget *widget,
}
}
+
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child),
+ NULL, &natural_size);
+ _gtk_plug_windowing_publish_natural_size (GTK_PLUG (widget), &natural_size);
}
static gboolean
diff --git a/gtk/gtkplugprivate.h b/gtk/gtkplugprivate.h
index 74f0374bc..83dcaaf7f 100644
--- a/gtk/gtkplugprivate.h
+++ b/gtk/gtkplugprivate.h
@@ -138,4 +138,7 @@ GdkFilterReturn _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
+void _gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
+ GtkRequisition *requisition);
+
#endif /* __GTK_PLUG_PRIVATE_H__ */
diff --git a/gtk/gtksocket-x11.c b/gtk/gtksocket-x11.c
index 5dbde457a..c076f9d0d 100644
--- a/gtk/gtksocket-x11.c
+++ b/gtk/gtksocket-x11.c
@@ -39,6 +39,7 @@
#include "gtkdnd.h"
#include "x11/gdkx.h"
+#include <X11/Xatom.h>
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
@@ -123,6 +124,63 @@ _gtk_socket_windowing_size_request (GtkSocket *socket)
}
void
+_gtk_socket_windowing_get_natural_size (GtkSocket *socket)
+{
+ GtkSocketPrivate *priv;
+ GdkDisplay *display;
+
+ Atom property, type;
+ int format, status;
+
+ unsigned long nitems, bytes_after;
+ unsigned char *data;
+ gint32 *data_long;
+
+ priv = _gtk_socket_get_private (socket);
+
+ priv->natural_width = 1;
+ priv->natural_height = 1;
+
+ if (GTK_WIDGET_MAPPED (socket))
+ {
+ display = gdk_drawable_get_display (socket->plug_window);
+ property = gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE");
+
+ gdk_error_trap_push ();
+ status = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ GDK_WINDOW_XWINDOW (socket->plug_window),
+ property, 0, 2, False, XA_CARDINAL,
+ &type, &format, &nitems, &bytes_after,
+ &data);
+ gdk_error_trap_pop ();
+
+ priv->have_natural_size = TRUE;
+
+ if (Success != status || !type)
+ return;
+
+ if (type != XA_CARDINAL)
+ {
+ g_warning ("_GTK_NATURAL_SIZE property has wrong type: %d\n", (int)type);
+ return;
+ }
+
+ if (nitems < 2)
+ {
+ g_warning ("_GTK_NATURAL_SIZE too short\n");
+ XFree (data);
+ return;
+ }
+
+ data_long = (gint32*) data;
+ priv->natural_width = MAX (1, data_long[0]);
+ priv->natural_height = MAX (1, data_long[1]);
+
+ XFree (data);
+ }
+}
+
+void
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
GdkEvent *gdk_event,
gboolean mask_key_presses)
@@ -602,6 +660,10 @@ _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
}
return_val = GDK_FILTER_REMOVE;
}
+ else if (xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (display, "_GTK_NATURAL_SIZE"))
+ {
+ _gtk_socket_windowing_get_natural_size (socket);
+ }
}
break;
case ReparentNotify:
diff --git a/gtk/gtksocket.c b/gtk/gtksocket.c
index f059f8d6d..c10934814 100644
--- a/gtk/gtksocket.c
+++ b/gtk/gtksocket.c
@@ -37,6 +37,7 @@
#include "gtksocket.h"
#include "gtksocketprivate.h"
#include "gtkdnd.h"
+#include "gtkextendedlayout.h"
#include "gtkintl.h"
#include "gtkalias.h"
@@ -67,6 +68,7 @@ static void gtk_socket_forall (GtkContainer *container,
GtkCallback callback,
gpointer callback_data);
+static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
/* Local data */
@@ -98,7 +100,10 @@ _gtk_socket_get_private (GtkSocket *socket)
return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
}
-G_DEFINE_TYPE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+ gtk_socket_extended_layout_interface_init))
+
static void
gtk_socket_finalize (GObject *object)
@@ -185,6 +190,8 @@ gtk_socket_class_init (GtkSocketClass *class)
static void
gtk_socket_init (GtkSocket *socket)
{
+ GtkSocketPrivate *priv;
+
socket->request_width = 0;
socket->request_height = 0;
socket->current_width = 0;
@@ -199,6 +206,9 @@ gtk_socket_init (GtkSocket *socket)
socket->accel_group = gtk_accel_group_new ();
g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
+
+ priv = _gtk_socket_get_private (socket);
+ priv->have_natural_size = FALSE;
}
/**
@@ -1000,5 +1010,65 @@ _gtk_socket_advance_toplevel_focus (GtkSocket *socket,
}
}
+static void
+gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout,
+ GtkRequisition *minimal_size,
+ GtkRequisition *desired_size)
+{
+ GtkSocket *socket = GTK_SOCKET (layout);
+ GtkSocketPrivate *priv;
+
+ if (socket->plug_widget)
+ {
+ gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (socket->plug_widget),
+ minimal_size,
+ desired_size);
+ }
+ else
+ {
+ priv = _gtk_socket_get_private (socket);
+
+ if (socket->is_mapped && !priv->have_natural_size && socket->plug_window)
+ {
+ _gtk_socket_windowing_size_request (socket);
+ _gtk_socket_windowing_get_natural_size (socket);
+ }
+
+ if (socket->is_mapped && priv->have_natural_size)
+ {
+ if (minimal_size)
+ {
+ minimal_size->width = MAX (socket->request_width, 1);
+ minimal_size->height = MAX (socket->request_height, 1);
+ }
+ if (desired_size)
+ {
+ desired_size->width = MAX (priv->natural_width, 1);
+ desired_size->height = MAX (priv->natural_height, 1);
+ }
+ }
+ else
+ {
+ if (minimal_size)
+ {
+ minimal_size->width = 1;
+ minimal_size->height = 1;
+ }
+ if (desired_size)
+ {
+ desired_size->width = 1;
+ desired_size->height = 1;
+ }
+ }
+ }
+}
+
+static void
+gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
+{
+ iface->get_desired_size = gtk_socket_extended_layout_get_desired_size;
+}
+
+
#define __GTK_SOCKET_C__
#include "gtkaliasdef.c"
diff --git a/gtk/gtksocketprivate.h b/gtk/gtksocketprivate.h
index 44a6c6b36..8eda1ae6b 100644
--- a/gtk/gtksocketprivate.h
+++ b/gtk/gtksocketprivate.h
@@ -31,6 +31,9 @@ typedef struct _GtkSocketPrivate GtkSocketPrivate;
struct _GtkSocketPrivate
{
gint resize_count;
+ gint natural_width;
+ gint natural_height;
+ gboolean have_natural_size;
};
/* In gtksocket.c: */
@@ -83,6 +86,7 @@ void _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket);
*/
void _gtk_socket_windowing_size_request (GtkSocket *socket);
+void _gtk_socket_windowing_get_natural_size (GtkSocket *socket);
/*
* _gtk_socket_windowing_send_key_event:
*