Commit c7e73be5 authored by Jan Djärv's avatar Jan Djärv
Browse files

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.
parent 247f696e
2011-06-26 Jan Djärv <jan.h.d@swipnet.se>
* emacsgtkfixed.h: State that this is only used with Gtk+3.
(emacs_fixed_set_min_size): Remove.
(emacs_fixed_new): Take frame as argument.
* 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 (Bug#8919).
(XSetWMSizeHints, XSetWMNormalHints): Override these functions
and use min_width/height from frames size_hint to set
min_width/height (Bug#8919).
* 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.
2011-06-26 Eli Zaretskii <eliz@gnu.org>
* bidi.c (bidi_paragraph_init): Test for ZV_BYTE before calling
......
/* 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);
}
/* A Gtk Widget that inherits GtkFixed, but can be shrinked.
/* 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.
......@@ -24,6 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
G_BEGIN_DECLS
struct frame;
#define EMACS_TYPE_FIXED (emacs_fixed_get_type ())
#define EMACS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMACS_TYPE_FIXED, EmacsFixed))
#define EMACS_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EMACS_TYPE_FIXED, EmacsFixedClass))
......@@ -49,8 +52,7 @@ struct _EmacsFixedClass
GtkFixedClass parent_class;
};
extern GtkWidget *emacs_fixed_new (void);
extern void emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height);
extern GtkWidget *emacs_fixed_new (struct frame *f);
extern GType emacs_fixed_get_type (void);
G_END_DECLS
......
......@@ -1086,7 +1086,7 @@ xg_create_frame_widgets (FRAME_PTR f)
whbox = gtk_hbox_new (FALSE, 0);
#ifdef HAVE_GTK3
wfixed = emacs_fixed_new ();
wfixed = emacs_fixed_new (f);
#else
wfixed = gtk_fixed_new ();
#endif
......@@ -1286,18 +1286,6 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
size_hints.min_width = base_width + min_cols * size_hints.width_inc;
size_hints.min_height = base_height + min_rows * size_hints.height_inc;
#ifdef HAVE_GTK3
/* Gtk3 ignores min width/height and overwrites them with its own idea
of min width/height. Put out min values to the widget so Gtk
gets the same value we want it to be. Without this, a user can't
shrink an Emacs frame.
*/
if (FRAME_GTK_WIDGET (f))
emacs_fixed_set_min_size (EMACS_FIXED (FRAME_GTK_WIDGET (f)),
size_hints.min_width,
size_hints.min_height);
#endif
/* These currently have a one to one mapping with the X values, but I
don't think we should rely on that. */
hint_flags |= GDK_HINT_WIN_GRAVITY;
......@@ -1336,7 +1324,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
{
BLOCK_INPUT;
gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
NULL, &size_hints, hint_flags);
NULL, &size_hints, hint_flags);
f->output_data.x->size_hints = size_hints;
f->output_data.x->hint_flags = hint_flags;
UNBLOCK_INPUT;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment