Implement extended layout for plug/socket
This commit is contained in:
parent
9a48091064
commit
56edab3553
@ -32,6 +32,7 @@
|
|||||||
#include "gtkplugprivate.h"
|
#include "gtkplugprivate.h"
|
||||||
|
|
||||||
#include "x11/gdkx.h"
|
#include "x11/gdkx.h"
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#include "gtkxembed.h"
|
#include "gtkxembed.h"
|
||||||
#include "gtkalias.h"
|
#include "gtkalias.h"
|
||||||
@ -330,3 +331,29 @@ _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
|
|||||||
|
|
||||||
return return_val;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "gtkmain.h"
|
#include "gtkmain.h"
|
||||||
#include "gtkmarshalers.h"
|
#include "gtkmarshalers.h"
|
||||||
#include "gtkplug.h"
|
#include "gtkplug.h"
|
||||||
|
#include "gtkextendedlayout.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
#include "gtkprivate.h"
|
#include "gtkprivate.h"
|
||||||
#include "gtkplugprivate.h"
|
#include "gtkplugprivate.h"
|
||||||
@ -721,6 +722,9 @@ static void
|
|||||||
gtk_plug_size_allocate (GtkWidget *widget,
|
gtk_plug_size_allocate (GtkWidget *widget,
|
||||||
GtkAllocation *allocation)
|
GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
|
GtkBin *bin = GTK_BIN (widget);
|
||||||
|
GtkRequisition natural_size;
|
||||||
|
|
||||||
if (GTK_WIDGET_TOPLEVEL (widget))
|
if (GTK_WIDGET_TOPLEVEL (widget))
|
||||||
GTK_WIDGET_CLASS (gtk_plug_parent_class)->size_allocate (widget, allocation);
|
GTK_WIDGET_CLASS (gtk_plug_parent_class)->size_allocate (widget, allocation);
|
||||||
else
|
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
|
static gboolean
|
||||||
|
@ -138,4 +138,7 @@ GdkFilterReturn _gtk_plug_windowing_filter_func (GdkXEvent *gdk_xevent,
|
|||||||
GdkEvent *event,
|
GdkEvent *event,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
void _gtk_plug_windowing_publish_natural_size (GtkPlug *plug,
|
||||||
|
GtkRequisition *requisition);
|
||||||
|
|
||||||
#endif /* __GTK_PLUG_PRIVATE_H__ */
|
#endif /* __GTK_PLUG_PRIVATE_H__ */
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "gtkdnd.h"
|
#include "gtkdnd.h"
|
||||||
|
|
||||||
#include "x11/gdkx.h"
|
#include "x11/gdkx.h"
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#ifdef HAVE_XFIXES
|
#ifdef HAVE_XFIXES
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
@ -122,6 +123,63 @@ _gtk_socket_windowing_size_request (GtkSocket *socket)
|
|||||||
gdk_error_trap_pop ();
|
gdk_error_trap_pop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
void
|
||||||
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
|
_gtk_socket_windowing_send_key_event (GtkSocket *socket,
|
||||||
GdkEvent *gdk_event,
|
GdkEvent *gdk_event,
|
||||||
@ -602,6 +660,10 @@ _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
|
|||||||
}
|
}
|
||||||
return_val = GDK_FILTER_REMOVE;
|
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;
|
break;
|
||||||
case ReparentNotify:
|
case ReparentNotify:
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "gtksocket.h"
|
#include "gtksocket.h"
|
||||||
#include "gtksocketprivate.h"
|
#include "gtksocketprivate.h"
|
||||||
#include "gtkdnd.h"
|
#include "gtkdnd.h"
|
||||||
|
#include "gtkextendedlayout.h"
|
||||||
#include "gtkintl.h"
|
#include "gtkintl.h"
|
||||||
|
|
||||||
#include "gtkalias.h"
|
#include "gtkalias.h"
|
||||||
@ -67,6 +68,7 @@ static void gtk_socket_forall (GtkContainer *container,
|
|||||||
GtkCallback callback,
|
GtkCallback callback,
|
||||||
gpointer callback_data);
|
gpointer callback_data);
|
||||||
|
|
||||||
|
static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
|
||||||
|
|
||||||
/* Local data */
|
/* Local data */
|
||||||
|
|
||||||
@ -98,7 +100,10 @@ _gtk_socket_get_private (GtkSocket *socket)
|
|||||||
return G_TYPE_INSTANCE_GET_PRIVATE (socket, GTK_TYPE_SOCKET, GtkSocketPrivate);
|
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
|
static void
|
||||||
gtk_socket_finalize (GObject *object)
|
gtk_socket_finalize (GObject *object)
|
||||||
@ -185,6 +190,8 @@ gtk_socket_class_init (GtkSocketClass *class)
|
|||||||
static void
|
static void
|
||||||
gtk_socket_init (GtkSocket *socket)
|
gtk_socket_init (GtkSocket *socket)
|
||||||
{
|
{
|
||||||
|
GtkSocketPrivate *priv;
|
||||||
|
|
||||||
socket->request_width = 0;
|
socket->request_width = 0;
|
||||||
socket->request_height = 0;
|
socket->request_height = 0;
|
||||||
socket->current_width = 0;
|
socket->current_width = 0;
|
||||||
@ -199,6 +206,9 @@ gtk_socket_init (GtkSocket *socket)
|
|||||||
|
|
||||||
socket->accel_group = gtk_accel_group_new ();
|
socket->accel_group = gtk_accel_group_new ();
|
||||||
g_object_set_data (G_OBJECT (socket->accel_group), I_("gtk-socket"), socket);
|
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__
|
#define __GTK_SOCKET_C__
|
||||||
#include "gtkaliasdef.c"
|
#include "gtkaliasdef.c"
|
||||||
|
@ -31,6 +31,9 @@ typedef struct _GtkSocketPrivate GtkSocketPrivate;
|
|||||||
struct _GtkSocketPrivate
|
struct _GtkSocketPrivate
|
||||||
{
|
{
|
||||||
gint resize_count;
|
gint resize_count;
|
||||||
|
gint natural_width;
|
||||||
|
gint natural_height;
|
||||||
|
gboolean have_natural_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* In gtksocket.c: */
|
/* 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_size_request (GtkSocket *socket);
|
||||||
|
|
||||||
|
void _gtk_socket_windowing_get_natural_size (GtkSocket *socket);
|
||||||
/*
|
/*
|
||||||
* _gtk_socket_windowing_send_key_event:
|
* _gtk_socket_windowing_send_key_event:
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user