Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2018-11-23 20:41:33 +0000
committerEric Williams2018-11-23 20:43:51 +0000
commit3f85ae3f2802cdd9d99296643a26231355709211 (patch)
treec637affbd3ef9a5a0f7d6571884dd98ff8099083
parentd53c584eda3df3e021b22226a63edc7cdb3e65c3 (diff)
downloadeclipse.platform.swt-3f85ae3f2802cdd9d99296643a26231355709211.tar.gz
eclipse.platform.swt-3f85ae3f2802cdd9d99296643a26231355709211.tar.xz
eclipse.platform.swt-3f85ae3f2802cdd9d99296643a26231355709211.zip
Bug 541107: [GTK4] Port native SwtFixed code to GTK4
Contribute SwtFixed native test snippet for GTK4. Change-Id: If3bc3d4f8a863521e4c313ad7cb4946e821d0326 Signed-off-by: Eric Williams <ericwill@redhat.com>
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/Makefile (renamed from tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/Makefile)0
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.c (renamed from tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.c)0
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.h (renamed from tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.h)0
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/simple_button_app.c (renamed from tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/simple_button_app.c)0
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/Makefile11
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.c435
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.h56
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/simple_button_app.c66
8 files changed, 568 insertions, 0 deletions
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/Makefile b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/Makefile
index c9ada3573c..c9ada3573c 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/Makefile
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/Makefile
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.c b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.c
index 36253d2ece..36253d2ece 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.c
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.c
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.h b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.h
index 6d9f08d7cb..6d9f08d7cb 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/os_custom.h
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/os_custom.h
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/simple_button_app.c b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/simple_button_app.c
index 4760ab1214..4760ab1214 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/simple_button_app.c
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK3/simple_button_app.c
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/Makefile b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/Makefile
new file mode 100644
index 0000000000..aa74dc752b
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/Makefile
@@ -0,0 +1,11 @@
+CFLAGS = `pkg-config --cflags gtk+-4.0` -g
+LIBS = `pkg-config --libs gtk+-4.0`
+OBJ = simple_button_app.o os_custom.o
+
+simple_button_app: $(OBJ)
+ $(CC) $(CFLAGS) -o simple_button_app $(OBJ) $(LIBS) $(LDFLAGS)
+
+clean:
+ $(RM) $(OBJ) simple_button_app
+
+all: simple_button_app
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.c b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.c
new file mode 100644
index 0000000000..c04f73f08f
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.c
@@ -0,0 +1,435 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+#include "os_custom.h"
+
+struct _SwtFixedPrivate {
+ GtkAdjustment *hadjustment;
+ GtkAdjustment *vadjustment;
+ guint hscroll_policy : 1;
+ guint vscroll_policy : 1;
+ GList *children;
+};
+
+struct _SwtFixedChild
+{
+ GtkWidget *widget;
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+};
+typedef struct _SwtFixedChild SwtFixedChild;
+
+enum {
+ PROP_0,
+ PROP_HADJUSTMENT,
+ PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY,
+};
+
+static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void swt_fixed_finalize (GObject *object);
+static void swt_fixed_realize (GtkWidget *widget);
+static void swt_fixed_map (GtkWidget *widget);
+static AtkObject *swt_fixed_get_accessible (GtkWidget *widget);
+static void swt_fixed_measure (GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum,
+ int *natural, int *minimum_baseline, int *natural_baseline);
+static void swt_fixed_size_allocate (GtkWidget *widget, const GtkAllocation *allocation, int baseline);
+static void swt_fixed_add (GtkContainer *container, GtkWidget *widget);
+static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget);
+static void swt_fixed_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data);
+
+G_DEFINE_TYPE_WITH_CODE (SwtFixed, swt_fixed, GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
+
+static void swt_fixed_class_init (SwtFixedClass *class) {
+ GObjectClass *gobject_class = (GObjectClass*) class;
+ GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
+ GtkContainerClass *container_class = (GtkContainerClass*) class;
+
+ /* GOject implementation */
+ gobject_class->set_property = swt_fixed_set_property;
+ gobject_class->get_property = swt_fixed_get_property;
+ gobject_class->finalize = swt_fixed_finalize;
+
+ /* Scrollable implemetation */
+ g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
+
+ /* Widget implementation */
+ widget_class->realize = swt_fixed_realize;
+ widget_class->map = swt_fixed_map;
+ widget_class->measure = swt_fixed_measure;
+ widget_class->size_allocate = swt_fixed_size_allocate;
+
+ /* Container implementation */
+ container_class->add = swt_fixed_add;
+ container_class->remove = swt_fixed_remove;
+ container_class->forall = swt_fixed_forall;
+
+ g_type_class_add_private (class, sizeof (SwtFixedPrivate));
+}
+
+void swt_fixed_restack (SwtFixed *fixed, GtkWidget *widget, GtkWidget *sibling, gboolean above) {
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+ SwtFixedChild *child, *sibling_child;
+
+ list = priv->children;
+ while (list) {
+ child = list->data;
+ if (child->widget == widget) break;
+ list = list->next;
+ }
+
+ if (!list) return;
+ priv->children = g_list_remove_link (priv->children, list);
+ g_list_free_1 (list);
+
+ list = NULL;
+ if (sibling) {
+ list = priv->children;
+ while (list) {
+ sibling_child = list->data;
+ if (sibling_child->widget == sibling) {
+ break;
+ }
+ list = list->next;
+ }
+ if (list) {
+ if (!above) list = list->next;
+ }
+ }
+ if (!list) {
+ list = above ? priv->children : NULL;
+ }
+ priv->children = g_list_insert_before (priv->children, list, child);
+
+ /*
+ {
+ GdkWindow *sibling_window = NULL;
+ if (list) {
+ child = list->data;
+ sibling_window = gtk_widget_get_window (child);
+ }
+ gdk_window_restack (gtk_widget_get_window (widget), sibling_window, above);
+ }
+ */
+}
+
+GtkWidget *swt_fixed_new(void) {
+
+ return GTK_WIDGET(g_object_new(SWT_TYPE_FIXED, NULL));
+}
+
+static void swt_fixed_init (SwtFixed *widget) {
+ SwtFixedPrivate *priv;
+
+ priv = widget->priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, SWT_TYPE_FIXED, SwtFixedPrivate);
+ priv->children = NULL;
+ priv->hadjustment = NULL;
+ priv->vadjustment = NULL;
+
+ gtk_widget_set_has_surface(GTK_WIDGET(widget), TRUE);
+}
+
+static void swt_fixed_finalize (GObject *object) {
+ SwtFixed *widget = SWT_FIXED (object);
+ SwtFixedPrivate *priv = widget->priv;
+
+ g_object_unref (priv->hadjustment);
+ g_object_unref (priv->vadjustment);
+
+ G_OBJECT_CLASS (swt_fixed_parent_class)->finalize (object);
+}
+
+static void swt_fixed_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
+ SwtFixed *widget = SWT_FIXED (object);
+ SwtFixedPrivate *priv = widget->priv;
+
+ switch (prop_id) {
+ case PROP_HADJUSTMENT:
+ g_value_set_object (value, priv->hadjustment);
+ break;
+ case PROP_VADJUSTMENT:
+ g_value_set_object (value, priv->vadjustment);
+ break;
+ case PROP_HSCROLL_POLICY:
+ g_value_set_enum (value, priv->hscroll_policy);
+ break;
+ case PROP_VSCROLL_POLICY:
+ g_value_set_enum (value, priv->vscroll_policy);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void swt_fixed_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
+ SwtFixed *widget = SWT_FIXED (object);
+ SwtFixedPrivate *priv = widget->priv;
+ GtkAdjustment *adjustment;
+
+ switch (prop_id) {
+ case PROP_HADJUSTMENT:
+ adjustment = g_value_get_object (value);
+ if (adjustment && priv->hadjustment == adjustment) return;
+ if (priv->hadjustment != NULL) g_object_unref (priv->hadjustment);
+ if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ priv->hadjustment = g_object_ref_sink (adjustment);
+ g_object_notify (G_OBJECT (widget), "hadjustment");
+ break;
+ case PROP_VADJUSTMENT:
+ adjustment = g_value_get_object (value);
+ if (adjustment && priv->vadjustment == adjustment) return;
+ if (priv->vadjustment != NULL) g_object_unref (priv->vadjustment);
+ if (adjustment == NULL) adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ priv->vadjustment = g_object_ref_sink (adjustment);
+ g_object_notify (G_OBJECT (widget), "vadjustment");
+ break;
+ case PROP_HSCROLL_POLICY:
+ priv->hscroll_policy = g_value_get_enum (value);
+ break;
+ case PROP_VSCROLL_POLICY:
+ priv->vscroll_policy = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void swt_fixed_realize (GtkWidget *widget) {
+ SwtFixed *fixed = SWT_FIXED (widget);
+ SwtFixedPrivate *priv = fixed->priv;
+ GtkAllocation allocation;
+ GdkSurface *surface;
+
+ if (!gtk_widget_get_has_surface (widget)) {
+ GTK_WIDGET_CLASS (swt_fixed_parent_class)->realize (widget);
+ return;
+ }
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ surface = gdk_surface_new_child (gtk_widget_get_parent_surface (widget), &allocation);
+ gtk_widget_set_surface(widget, surface);
+ gdk_surface_set_user_data (surface, widget);
+ return GTK_WIDGET_CLASS (swt_fixed_parent_class)->realize (widget);
+}
+
+static void swt_fixed_map (GtkWidget *widget) {
+ SwtFixed *fixed = SWT_FIXED (widget);
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+
+ list = priv->children;
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+ list = list->next;
+ if (gtk_widget_get_visible (child)) {
+ if (!gtk_widget_get_mapped (child)) gtk_widget_map (child);
+ }
+ }
+ if (gtk_widget_get_has_surface (widget)) {
+ //NOTE: contrary to most of GTK, swt_fixed_* container does not raise windows upon showing them.
+ //This has the effect that widgets are drawn *beneath* the previous one.
+ //E.g if this line is changed to gdk_window_show (..) then widgets are drawn on top of the previous one.
+ //This affects mostly only the absolute layout with overlapping widgets, e.g minimizied panels that
+ //pop-out in Eclipse (aka fast-view).
+ //As such, be attentive to swt_fixed_forall(..); traversing children may need to be done in reverse in some
+ //cases.
+ gdk_surface_show_unraised (gtk_widget_get_surface (widget));
+ }
+ return GTK_WIDGET_CLASS (swt_fixed_parent_class)->map (widget);
+}
+
+static void swt_fixed_measure (GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum,
+ int *natural, int *minimum_baseline, int *natural_baseline) {
+ natural = 0;
+ natural_baseline = 0;
+ minimum = 0;
+ minimum_baseline = 0;
+ return;
+}
+
+static void swt_fixed_size_allocate (GtkWidget *widget, const GtkAllocation *allocation, int baseline) {
+ SwtFixed *fixed = SWT_FIXED (widget);
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+ GtkAllocation child_allocation;
+ GtkRequisition requisition;
+ gint w, h;
+
+ if (gtk_widget_get_has_surface (widget)) {
+ if (gtk_widget_get_realized (widget)) {
+ gdk_surface_move_resize (gtk_widget_get_surface (widget), allocation->x, allocation->y, allocation->width, allocation->height);
+ }
+ }
+
+ list = priv->children;
+
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+ list = list->next;
+
+ child_allocation.x = child_data->x;
+ child_allocation.y = child_data->y;
+ if (!gtk_widget_get_has_surface (widget)) {
+ child_allocation.x += allocation->x;
+ child_allocation.y += allocation->y;
+ }
+
+ w = child_data->width;
+ h = child_data->height;
+ if (w == -1 || h == -1) {
+ gtk_widget_get_preferred_size (child, &requisition, NULL);
+ if (w == -1) w = requisition.width;
+ if (h == -1) h = requisition.height;
+ }
+ // Feature in GTK: gtk_widget_preferred_size() has to be called before
+ // gtk_widget_size_allocate otherwise a warning is thrown. See Bug 486068.
+ gtk_widget_get_preferred_size (child, &requisition, NULL);
+
+ child_allocation.width = w;
+ child_allocation.height = h;
+
+ gtk_widget_size_allocate (child, &child_allocation, -1);
+ }
+}
+
+void swt_fixed_move (SwtFixed *fixed, GtkWidget *widget, gint x, gint y) {
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+
+ list = priv->children;
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+ if (child == widget) {
+ child_data->x = x;
+ child_data->y = y;
+ break;
+ }
+ list = list->next;
+ }
+}
+
+void swt_fixed_resize (SwtFixed *fixed, GtkWidget *widget, gint width, gint height) {
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+
+ list = priv->children;
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+ if (child == widget) {
+ child_data->width = width;
+ child_data->height = height;
+
+ /*
+ * Feature in GTK: sometimes the sizing of child SwtFixed widgets
+ * does not happen quickly enough, causing miscalculations in SWT.
+ * Allocate the size of the child directly when swt_fixed_resize()
+ * is called. See bug 487160.
+ */
+ GtkAllocation allocation, to_allocate;
+ GtkRequisition req;
+ gtk_widget_get_allocation(child, &allocation);
+
+ // Keep x and y values the same to prevent misplaced containers
+ to_allocate.x = allocation.x;
+ to_allocate.y = allocation.y;
+ to_allocate.width = width;
+ to_allocate.height = height;
+
+ // Call gtk_widget_get_preferred_size() and finish the allocation.
+ gtk_widget_get_preferred_size (child, &req, NULL);
+ gtk_widget_size_allocate(child, &to_allocate, -1);
+ break;
+ }
+ list = list->next;
+ }
+}
+
+static void swt_fixed_add (GtkContainer *container, GtkWidget *child) {
+ GtkWidget *widget = GTK_WIDGET (container);
+ SwtFixed *fixed = SWT_FIXED (container);
+ SwtFixedPrivate *priv = fixed->priv;
+ SwtFixedChild *child_data;
+
+ child_data = g_new (SwtFixedChild, 1);
+ child_data->widget = child;
+ child_data->x = child_data->y = 0;
+ child_data->width = child_data->height = -1;
+
+ priv->children = g_list_append (priv->children, child_data);
+ gtk_widget_set_parent (child, widget);
+}
+
+static void swt_fixed_remove (GtkContainer *container, GtkWidget *widget) {
+ SwtFixed *fixed = SWT_FIXED (container);
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+
+ list = priv->children;
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+ if (child == widget) {
+ gtk_widget_unparent (widget);
+ priv->children = g_list_remove_link (priv->children, list);
+ g_list_free_1 (list);
+ g_free (child_data);
+ break;
+ }
+ list = list->next;
+ }
+}
+
+static void swt_fixed_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data) {
+ SwtFixed *fixed = SWT_FIXED (container);
+ SwtFixedPrivate *priv = fixed->priv;
+ GList *list;
+
+ list = priv->children;
+
+ // NOTE: The direction of the list traversal is conditional.
+ //
+ // 1) When we do a *_foreach() traversal (i.e, include_internals==FALSE), we traverse the list as normal
+ // from front to back.
+ // This is used to layout higher level widgets inside containers (e.g row/grid etc..) in the expected way.
+ // If for a non-internal traversal we were to go in reverse, then widgets would get laid out in inverse order.
+ // 2) When we do a *_forall() traversal (i.e, include_internals==TRUE), we traverse the list in *reverse* order.
+ // This is an internal traversal of the internals of a widget. Reverse traversal is necessary for things like
+ // DnD Drop and DnD Motion events to find the correct widget in the case of overlapping widgets on an absolute layout.
+ // Reversal is required because in swt_fixed_map(..) we do not raise the widget when we show it, as a result
+ // the stack is in reverse.
+
+ while (list) {
+ SwtFixedChild *child_data = list->data;
+ GtkWidget *child = child_data->widget;
+
+ list = list->next;
+
+ (* callback) (child, callback_data);
+ }
+}
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.h b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.h
new file mode 100644
index 0000000000..6d9f08d7cb
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/os_custom.h
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+
+#ifndef OS_CUSTOM_H
+#define OS_CUSTOM_H
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#ifndef NO_SwtFixed
+#define SWT_TYPE_FIXED (swt_fixed_get_type ())
+#define SWT_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWT_TYPE_FIXED, SwtFixed))
+#define SWT_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWT_TYPE_FIXED, SwtFixedClass))
+#define SWT_IS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWT_TYPE_FIXED))
+#define SWT_IS_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWT_TYPE_FIXED))
+#define SWT_FIXED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWT_TYPE_FIXED, SwtFixedClass))
+
+
+typedef struct _SwtFixed SwtFixed;
+typedef struct _SwtFixedPrivate SwtFixedPrivate;
+typedef struct _SwtFixedClass SwtFixedClass;
+
+struct _SwtFixed
+{
+ GtkContainer container;
+
+ /*< private >*/
+ SwtFixedPrivate *priv;
+};
+
+struct _SwtFixedClass
+{
+ GtkContainerClass parent_class;
+};
+
+GType swt_fixed_get_type (void) G_GNUC_CONST;
+GtkWidget *swt_fixed_new(void);
+
+void swt_fixed_restack(SwtFixed *fixed, GtkWidget *widget, GtkWidget *sibling, gboolean above);
+void swt_fixed_move(SwtFixed *fixed, GtkWidget *widget, gint x, gint y);
+void swt_fixed_resize(SwtFixed *fixed, GtkWidget *widget, gint width, gint height);
+
+#endif
+#endif /* OS_CUSTOM_H */
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/simple_button_app.c b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/simple_button_app.c
new file mode 100644
index 0000000000..63e92310bc
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualNativeCTests/SwtFixed_native/GTK4/simple_button_app.c
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Red Hat and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Red Hat - initial API and implementation
+ *******************************************************************************/
+
+#include <gtk/gtk.h>
+#include "os_custom.h"
+
+static void
+activate (GtkApplication *app,
+ gpointer user_data)
+{
+
+ GtkWidget *window;
+ GtkWidget *button;
+ GtkWidget *button_box;
+ GtkWidget *vbox;
+ GtkWidget *fixed;
+ GtkWidget *scrolled;
+
+ window = gtk_application_window_new (app);
+ gtk_window_set_title (GTK_WINDOW (window), "Window");
+ gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (vbox), scrolled);
+
+ fixed = swt_fixed_new ();
+ gtk_container_add (GTK_CONTAINER (scrolled), fixed);
+
+ button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+
+ button = gtk_button_new_with_label ("Hello");
+ gtk_container_add (GTK_CONTAINER (button_box), button);
+ gtk_container_add (GTK_CONTAINER (fixed), button_box);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ gtk_widget_show (window);
+}
+
+int
+main (int argc,
+ char **argv)
+{
+
+ GtkApplication *app;
+ int status;
+
+ app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
+ g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
+ status = g_application_run (G_APPLICATION (app), argc, argv);
+ g_object_unref (app);
+
+ return status;
+}

Back to the top