diff options
author | Jan Djärv <jan.h.d@swipnet.se> | 2011-06-26 20:47:07 +0200 |
---|---|---|
committer | Jan Djärv <jan.h.d@swipnet.se> | 2011-06-26 20:47:07 +0200 |
commit | c7e73be5f7c8f5d24757ace235bc622a9a7fdcd0 (patch) | |
tree | d32a59317249eaa9958627f1a6a3584db670ba46 /src/emacsgtkfixed.c | |
parent | 247f696e50461a50306bc77d3683007bd06e8ba7 (diff) | |
download | emacs-c7e73be5f7c8f5d24757ace235bc622a9a7fdcd0.tar.gz |
Fix wm_size-hints race between KDE/KWin and Gtk+ 3.
* emacsgtkfixed.c: State that this is only used with Gtk+3.
(_EmacsFixedPrivate): Remove minwidth/height.
Add struct frame *f.
(emacs_fixed_init): Initialize priv->f.
(get_parent_class, emacs_fixed_set_min_size): Remove.
(emacs_fixed_new): Set priv->f to argument.
(emacs_fixed_get_preferred_width)
(emacs_fixed_get_preferred_height): Use min_width/height from
frames size_hint to set minimum and natural.
(XSetWMSizeHints, XSetWMNormalHints): Override these functions
and use min_width/height from frames size_hint to set
min_width/height (Bug#8919).
* emacsgtkfixed.h: State that this is only used with Gtk+3.
(emacs_fixed_set_min_size): Remove.
(emacs_fixed_new): Take frame as argument.
* gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new.
(x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size. Fix
indentation.
Diffstat (limited to 'src/emacsgtkfixed.c')
-rw-r--r-- | src/emacsgtkfixed.c | 101 |
1 files changed, 72 insertions, 29 deletions
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c index fe3514bce93..0b57e2cdf36 100644 --- a/src/emacsgtkfixed.c +++ b/src/emacsgtkfixed.c @@ -1,4 +1,5 @@ /* A Gtk Widget that inherits GtkFixed, but can be shrinked. +This file is only use when compiling with Gtk+ 3. Copyright (C) 2011 Free Software Foundation, Inc. @@ -17,12 +18,19 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ -#include "emacsgtkfixed.h" +#include <config.h> +#include "emacsgtkfixed.h" +#include <signal.h> +#include <stdio.h> +#include <setjmp.h> +#include "lisp.h" +#include "frame.h" +#include "xterm.h" struct _EmacsFixedPrivate { - int minwidth, minheight; + struct frame *f; }; @@ -59,7 +67,7 @@ emacs_fixed_init (EmacsFixed *fixed) { fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED, EmacsFixedPrivate); - fixed->priv->minwidth = fixed->priv->minheight = 0; + fixed->priv->f = 0; } /** @@ -70,17 +78,12 @@ emacs_fixed_init (EmacsFixed *fixed) * Returns: a new #EmacsFixed. */ GtkWidget* -emacs_fixed_new (void) -{ - return g_object_new (EMACS_TYPE_FIXED, NULL); -} - -static GtkWidgetClass * -get_parent_class (EmacsFixed *fixed) +emacs_fixed_new (struct frame *f) { - EmacsFixedClass *klass = EMACS_FIXED_GET_CLASS (fixed); - GtkFixedClass *parent_class = g_type_class_peek_parent (klass); - return (GtkWidgetClass*) parent_class; + EmacsFixed *fixed = g_object_new (EMACS_TYPE_FIXED, NULL); + EmacsFixedPrivate *priv = fixed->priv; + priv->f = f; + return GTK_WIDGET (fixed); } static void @@ -90,9 +93,9 @@ emacs_fixed_get_preferred_width (GtkWidget *widget, { EmacsFixed *fixed = EMACS_FIXED (widget); EmacsFixedPrivate *priv = fixed->priv; - GtkWidgetClass *widget_class = get_parent_class (fixed); - widget_class->get_preferred_width (widget, minimum, natural); - if (minimum) *minimum = priv->minwidth; + int w = priv->f->output_data.x->size_hints.min_width; + if (minimum) *minimum = w; + if (natural) *natural = w; } static void @@ -102,22 +105,62 @@ emacs_fixed_get_preferred_height (GtkWidget *widget, { EmacsFixed *fixed = EMACS_FIXED (widget); EmacsFixedPrivate *priv = fixed->priv; - GtkWidgetClass *widget_class = get_parent_class (fixed); - widget_class->get_preferred_height (widget, minimum, natural); - if (minimum) *minimum = priv->minheight; + int h = priv->f->output_data.x->size_hints.min_height; + if (minimum) *minimum = h; + if (natural) *natural = h; } + +/* Override the X function so we can intercept Gtk+ 3 calls. + Use our values for min_width/height so that KDE don't freak out + (Bug#8919), and so users can resize our frames as they wish. */ + void -emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height) +XSetWMSizeHints(Display* d, + Window w, + XSizeHints* hints, + Atom prop) { - EmacsFixedPrivate *priv = widget->priv; - GtkWidgetClass *widget_class = get_parent_class (widget); - int mw, nw, mh, nh; - - widget_class->get_preferred_height (GTK_WIDGET (widget), &mh, &nh); - widget_class->get_preferred_width (GTK_WIDGET (widget), &mw, &nw); + struct x_display_info *dpyinfo = x_display_info_for_display (d); + struct frame *f = x_top_window_to_frame (dpyinfo, w); + long data[18]; + data[0] = hints->flags; + data[1] = hints->x; + data[2] = hints->y; + data[3] = hints->width; + data[4] = hints->height; + data[5] = hints->min_width; + data[6] = hints->min_height; + data[7] = hints->max_width; + data[8] = hints->max_height; + data[9] = hints->width_inc; + data[10] = hints->height_inc; + data[11] = hints->min_aspect.x; + data[12] = hints->min_aspect.y; + data[13] = hints->max_aspect.x; + data[14] = hints->max_aspect.y; + data[15] = hints->base_width; + data[16] = hints->base_height; + data[17] = hints->win_gravity; + + if ((hints->flags & PMinSize) && f) + { + int w = f->output_data.x->size_hints.min_width; + int h = f->output_data.x->size_hints.min_height; + data[5] = w; + data[6] = h; + } + + XChangeProperty (d, w, prop, XA_WM_SIZE_HINTS, 32, PropModeReplace, + (unsigned char *) data, 18); +} - /* Gtk complains if min size is less than natural size. */ - if (width <= nw) priv->minwidth = width; - if (height <= nh) priv->minheight = height; +/* Override this X11 function. + This function is in the same X11 file as the one above. So we must + provide it also. */ + +void +XSetWMNormalHints (Display *d, Window w, XSizeHints *hints) +{ + XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS); } |