]> code.delx.au - gnu-emacs/blobdiff - src/emacsgtkfixed.c
Ibuffer change marks
[gnu-emacs] / src / emacsgtkfixed.c
index 1a62b59b7afb7c8d69fea7ee117c5b9d5f284d04..c04adf28b3672ebf57a33846847ec8c487fdfad9 100644 (file)
@@ -1,14 +1,14 @@
 /* A Gtk Widget that inherits GtkFixed, but can be shrunk.
 This file is only use when compiling with Gtk+ 3.
 
-Copyright (C) 2011-201 Free Software Foundation, Inc.
+Copyright (C) 2011-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs 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 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -20,35 +20,21 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
-#include "emacsgtkfixed.h"
-#include <signal.h>
-#include <stdio.h>
-#include <setjmp.h>
 #include "lisp.h"
 #include "frame.h"
 #include "xterm.h"
+#include "xwidget.h"
+#include "emacsgtkfixed.h"
 
-#define EMACS_TYPE_FIXED emacs_fixed_get_type ()
-#define EMACS_FIXED(obj) \
-  G_TYPE_CHECK_INSTANCE_CAST (obj, EMACS_TYPE_FIXED, EmacsFixed)
+/* Silence a bogus diagnostic; see GNOME bug 683906.  */
+#if GNUC_PREREQ (4, 7, 0) && ! GLIB_CHECK_VERSION (2, 35, 7)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif
 
 typedef struct _EmacsFixed EmacsFixed;
-typedef struct _EmacsFixedPrivate EmacsFixedPrivate;
 typedef struct _EmacsFixedClass EmacsFixedClass;
 
-struct _EmacsFixed
-{
-  GtkFixed container;
-
-  /*< private >*/
-  EmacsFixedPrivate *priv;
-};
-
-struct _EmacsFixedClass
-{
-  GtkFixedClass parent_class;
-};
-
 struct _EmacsFixedPrivate
 {
   struct frame *f;
@@ -64,6 +50,99 @@ static void emacs_fixed_get_preferred_height (GtkWidget *widget,
 static GType emacs_fixed_get_type (void);
 G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
 
+static EmacsFixed *
+EMACS_FIXED (GtkWidget *widget)
+{
+  return G_TYPE_CHECK_INSTANCE_CAST (widget, emacs_fixed_get_type (),
+                                    EmacsFixed);
+}
+
+#ifdef HAVE_XWIDGETS
+
+static EmacsFixedClass *
+EMACS_FIXED_GET_CLASS (GtkWidget *widget)
+{
+  return G_TYPE_INSTANCE_GET_CLASS (widget, emacs_fixed_get_type (),
+                                   EmacsFixedClass);
+}
+
+struct GtkFixedPrivateL
+{
+  GList *children;
+};
+
+static void
+emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
+                                     GtkAllocation *allocation)
+{
+  /* For xwidgets.
+
+     This basically re-implements the base class method and adds an
+     additional case for an xwidget view.
+
+     It would be nicer if the bse class method could be called first,
+     and the the xview modification only would remain here. It wasn't
+     possible to solve it that way yet.  */
+  EmacsFixedClass *klass;
+  GtkWidgetClass *parent_class;
+  struct GtkFixedPrivateL *priv;
+
+  klass = EMACS_FIXED_GET_CLASS (widget);
+  parent_class = g_type_class_peek_parent (klass);
+  parent_class->size_allocate (widget, allocation);
+
+  priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, GTK_TYPE_FIXED,
+                                     struct GtkFixedPrivateL);
+
+  gtk_widget_set_allocation (widget, allocation);
+
+  if (gtk_widget_get_has_window (widget))
+    {
+      if (gtk_widget_get_realized (widget))
+        gdk_window_move_resize (gtk_widget_get_window (widget),
+                                allocation->x,
+                                allocation->y,
+                                allocation->width,
+                                allocation->height);
+    }
+
+  for (GList *children = priv->children; children; children = children->next)
+    {
+      GtkFixedChild *child = children->data;
+
+      if (!gtk_widget_get_visible (child->widget))
+        continue;
+
+      GtkRequisition child_requisition;
+      gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
+
+      GtkAllocation child_allocation;
+      child_allocation.x = child->x;
+      child_allocation.y = child->y;
+
+      if (!gtk_widget_get_has_window (widget))
+        {
+          child_allocation.x += allocation->x;
+          child_allocation.y += allocation->y;
+        }
+
+      child_allocation.width = child_requisition.width;
+      child_allocation.height = child_requisition.height;
+
+      struct xwidget_view *xv
+        = g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
+      if (xv)
+        {
+          child_allocation.width = xv->clip_right;
+          child_allocation.height = xv->clip_bottom - xv->clip_top;
+        }
+
+      gtk_widget_size_allocate (child->widget, &child_allocation);
+    }
+}
+
+#endif  /* HAVE_XWIDGETS */
+
 static void
 emacs_fixed_class_init (EmacsFixedClass *klass)
 {
@@ -73,28 +152,24 @@ emacs_fixed_class_init (EmacsFixedClass *klass)
 
   widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
   widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
+#ifdef HAVE_XWIDGETS
+  widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate;
+#endif
   g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
 }
 
 static void
 emacs_fixed_init (EmacsFixed *fixed)
 {
-  fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED,
+  fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, emacs_fixed_get_type (),
                                              EmacsFixedPrivate);
   fixed->priv->f = 0;
 }
 
-/**
- * emacs_fixed_new:
- *
- * Creates a new #EmacsFixed.
- *
- * Returns: a new #EmacsFixed.
- */
-GtkWidget*
+GtkWidget *
 emacs_fixed_new (struct frame *f)
 {
-  EmacsFixed *fixed = g_object_new (EMACS_TYPE_FIXED, NULL);
+  EmacsFixed *fixed = g_object_new (emacs_fixed_get_type (), NULL);
   EmacsFixedPrivate *priv = fixed->priv;
   priv->f = f;
   return GTK_WIDGET (fixed);