aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Djärv2011-06-26 20:47:07 +0200
committerJan Djärv2011-06-26 20:47:07 +0200
commitc7e73be5f7c8f5d24757ace235bc622a9a7fdcd0 (patch)
treed32a59317249eaa9958627f1a6a3584db670ba46
parent247f696e50461a50306bc77d3683007bd06e8ba7 (diff)
downloademacs-c7e73be5f7c8f5d24757ace235bc622a9a7fdcd0.tar.gz
emacs-c7e73be5f7c8f5d24757ace235bc622a9a7fdcd0.zip
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.
-rw-r--r--src/ChangeLog23
-rw-r--r--src/emacsgtkfixed.c101
-rw-r--r--src/emacsgtkfixed.h8
-rw-r--r--src/gtkutil.c16
4 files changed, 102 insertions, 46 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1b395f865c8..8a25b736cd2 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,26 @@
12011-06-26 Jan Djärv <jan.h.d@swipnet.se>
2
3 * emacsgtkfixed.h: State that this is only used with Gtk+3.
4 (emacs_fixed_set_min_size): Remove.
5 (emacs_fixed_new): Take frame as argument.
6
7 * emacsgtkfixed.c: State that this is only used with Gtk+3.
8 (_EmacsFixedPrivate): Remove minwidth/height.
9 Add struct frame *f.
10 (emacs_fixed_init): Initialize priv->f.
11 (get_parent_class, emacs_fixed_set_min_size): Remove.
12 (emacs_fixed_new): Set priv->f to argument.
13 (emacs_fixed_get_preferred_width)
14 (emacs_fixed_get_preferred_height): Use min_width/height from
15 frames size_hint to set minimum and natural (Bug#8919).
16 (XSetWMSizeHints, XSetWMNormalHints): Override these functions
17 and use min_width/height from frames size_hint to set
18 min_width/height (Bug#8919).
19
20 * gtkutil.c (xg_create_frame_widgets): Pass f to emacs_fixed_new.
21 (x_wm_set_size_hint): Remove call to emacs_fixed_set_min_size. Fix
22 indentation.
23
12011-06-26 Eli Zaretskii <eliz@gnu.org> 242011-06-26 Eli Zaretskii <eliz@gnu.org>
2 25
3 * bidi.c (bidi_paragraph_init): Test for ZV_BYTE before calling 26 * bidi.c (bidi_paragraph_init): Test for ZV_BYTE before calling
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 @@
1/* A Gtk Widget that inherits GtkFixed, but can be shrinked. 1/* A Gtk Widget that inherits GtkFixed, but can be shrinked.
2This file is only use when compiling with Gtk+ 3.
2 3
3Copyright (C) 2011 Free Software Foundation, Inc. 4Copyright (C) 2011 Free Software Foundation, Inc.
4 5
@@ -17,12 +18,19 @@ GNU General Public License for more details.
17You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 20
20#include "emacsgtkfixed.h" 21#include <config.h>
21 22
23#include "emacsgtkfixed.h"
24#include <signal.h>
25#include <stdio.h>
26#include <setjmp.h>
27#include "lisp.h"
28#include "frame.h"
29#include "xterm.h"
22 30
23struct _EmacsFixedPrivate 31struct _EmacsFixedPrivate
24{ 32{
25 int minwidth, minheight; 33 struct frame *f;
26}; 34};
27 35
28 36
@@ -59,7 +67,7 @@ emacs_fixed_init (EmacsFixed *fixed)
59{ 67{
60 fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED, 68 fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, EMACS_TYPE_FIXED,
61 EmacsFixedPrivate); 69 EmacsFixedPrivate);
62 fixed->priv->minwidth = fixed->priv->minheight = 0; 70 fixed->priv->f = 0;
63} 71}
64 72
65/** 73/**
@@ -70,17 +78,12 @@ emacs_fixed_init (EmacsFixed *fixed)
70 * Returns: a new #EmacsFixed. 78 * Returns: a new #EmacsFixed.
71 */ 79 */
72GtkWidget* 80GtkWidget*
73emacs_fixed_new (void) 81emacs_fixed_new (struct frame *f)
74{
75 return g_object_new (EMACS_TYPE_FIXED, NULL);
76}
77
78static GtkWidgetClass *
79get_parent_class (EmacsFixed *fixed)
80{ 82{
81 EmacsFixedClass *klass = EMACS_FIXED_GET_CLASS (fixed); 83 EmacsFixed *fixed = g_object_new (EMACS_TYPE_FIXED, NULL);
82 GtkFixedClass *parent_class = g_type_class_peek_parent (klass); 84 EmacsFixedPrivate *priv = fixed->priv;
83 return (GtkWidgetClass*) parent_class; 85 priv->f = f;
86 return GTK_WIDGET (fixed);
84} 87}
85 88
86static void 89static void
@@ -90,9 +93,9 @@ emacs_fixed_get_preferred_width (GtkWidget *widget,
90{ 93{
91 EmacsFixed *fixed = EMACS_FIXED (widget); 94 EmacsFixed *fixed = EMACS_FIXED (widget);
92 EmacsFixedPrivate *priv = fixed->priv; 95 EmacsFixedPrivate *priv = fixed->priv;
93 GtkWidgetClass *widget_class = get_parent_class (fixed); 96 int w = priv->f->output_data.x->size_hints.min_width;
94 widget_class->get_preferred_width (widget, minimum, natural); 97 if (minimum) *minimum = w;
95 if (minimum) *minimum = priv->minwidth; 98 if (natural) *natural = w;
96} 99}
97 100
98static void 101static void
@@ -102,22 +105,62 @@ emacs_fixed_get_preferred_height (GtkWidget *widget,
102{ 105{
103 EmacsFixed *fixed = EMACS_FIXED (widget); 106 EmacsFixed *fixed = EMACS_FIXED (widget);
104 EmacsFixedPrivate *priv = fixed->priv; 107 EmacsFixedPrivate *priv = fixed->priv;
105 GtkWidgetClass *widget_class = get_parent_class (fixed); 108 int h = priv->f->output_data.x->size_hints.min_height;
106 widget_class->get_preferred_height (widget, minimum, natural); 109 if (minimum) *minimum = h;
107 if (minimum) *minimum = priv->minheight; 110 if (natural) *natural = h;
108} 111}
109 112
113
114/* Override the X function so we can intercept Gtk+ 3 calls.
115 Use our values for min_width/height so that KDE don't freak out
116 (Bug#8919), and so users can resize our frames as they wish. */
117
110void 118void
111emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height) 119XSetWMSizeHints(Display* d,
120 Window w,
121 XSizeHints* hints,
122 Atom prop)
112{ 123{
113 EmacsFixedPrivate *priv = widget->priv; 124 struct x_display_info *dpyinfo = x_display_info_for_display (d);
114 GtkWidgetClass *widget_class = get_parent_class (widget); 125 struct frame *f = x_top_window_to_frame (dpyinfo, w);
115 int mw, nw, mh, nh; 126 long data[18];
116 127 data[0] = hints->flags;
117 widget_class->get_preferred_height (GTK_WIDGET (widget), &mh, &nh); 128 data[1] = hints->x;
118 widget_class->get_preferred_width (GTK_WIDGET (widget), &mw, &nw); 129 data[2] = hints->y;
130 data[3] = hints->width;
131 data[4] = hints->height;
132 data[5] = hints->min_width;
133 data[6] = hints->min_height;
134 data[7] = hints->max_width;
135 data[8] = hints->max_height;
136 data[9] = hints->width_inc;
137 data[10] = hints->height_inc;
138 data[11] = hints->min_aspect.x;
139 data[12] = hints->min_aspect.y;
140 data[13] = hints->max_aspect.x;
141 data[14] = hints->max_aspect.y;
142 data[15] = hints->base_width;
143 data[16] = hints->base_height;
144 data[17] = hints->win_gravity;
145
146 if ((hints->flags & PMinSize) && f)
147 {
148 int w = f->output_data.x->size_hints.min_width;
149 int h = f->output_data.x->size_hints.min_height;
150 data[5] = w;
151 data[6] = h;
152 }
153
154 XChangeProperty (d, w, prop, XA_WM_SIZE_HINTS, 32, PropModeReplace,
155 (unsigned char *) data, 18);
156}
119 157
120 /* Gtk complains if min size is less than natural size. */ 158/* Override this X11 function.
121 if (width <= nw) priv->minwidth = width; 159 This function is in the same X11 file as the one above. So we must
122 if (height <= nh) priv->minheight = height; 160 provide it also. */
161
162void
163XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
164{
165 XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);
123} 166}
diff --git a/src/emacsgtkfixed.h b/src/emacsgtkfixed.h
index 405374373ec..dbac136bd7f 100644
--- a/src/emacsgtkfixed.h
+++ b/src/emacsgtkfixed.h
@@ -1,4 +1,5 @@
1/* A Gtk Widget that inherits GtkFixed, but can be shrinked. 1/* A Gtk Widget that inherits GtkFixed, but can be shrinked.
2This file is only use when compiling with Gtk+ 3.
2 3
3Copyright (C) 2011 Free Software Foundation, Inc. 4Copyright (C) 2011 Free Software Foundation, Inc.
4 5
@@ -24,6 +25,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24 25
25G_BEGIN_DECLS 26G_BEGIN_DECLS
26 27
28struct frame;
29
27#define EMACS_TYPE_FIXED (emacs_fixed_get_type ()) 30#define EMACS_TYPE_FIXED (emacs_fixed_get_type ())
28#define EMACS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMACS_TYPE_FIXED, EmacsFixed)) 31#define EMACS_FIXED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMACS_TYPE_FIXED, EmacsFixed))
29#define EMACS_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EMACS_TYPE_FIXED, EmacsFixedClass)) 32#define EMACS_FIXED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EMACS_TYPE_FIXED, EmacsFixedClass))
@@ -49,8 +52,7 @@ struct _EmacsFixedClass
49 GtkFixedClass parent_class; 52 GtkFixedClass parent_class;
50}; 53};
51 54
52extern GtkWidget *emacs_fixed_new (void); 55extern GtkWidget *emacs_fixed_new (struct frame *f);
53extern void emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height);
54extern GType emacs_fixed_get_type (void); 56extern GType emacs_fixed_get_type (void);
55 57
56G_END_DECLS 58G_END_DECLS
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 6c00058e7af..343fcfa083a 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1086,7 +1086,7 @@ xg_create_frame_widgets (FRAME_PTR f)
1086 whbox = gtk_hbox_new (FALSE, 0); 1086 whbox = gtk_hbox_new (FALSE, 0);
1087 1087
1088#ifdef HAVE_GTK3 1088#ifdef HAVE_GTK3
1089 wfixed = emacs_fixed_new (); 1089 wfixed = emacs_fixed_new (f);
1090#else 1090#else
1091 wfixed = gtk_fixed_new (); 1091 wfixed = gtk_fixed_new ();
1092#endif 1092#endif
@@ -1286,18 +1286,6 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
1286 size_hints.min_width = base_width + min_cols * size_hints.width_inc; 1286 size_hints.min_width = base_width + min_cols * size_hints.width_inc;
1287 size_hints.min_height = base_height + min_rows * size_hints.height_inc; 1287 size_hints.min_height = base_height + min_rows * size_hints.height_inc;
1288 1288
1289#ifdef HAVE_GTK3
1290 /* Gtk3 ignores min width/height and overwrites them with its own idea
1291 of min width/height. Put out min values to the widget so Gtk
1292 gets the same value we want it to be. Without this, a user can't
1293 shrink an Emacs frame.
1294 */
1295 if (FRAME_GTK_WIDGET (f))
1296 emacs_fixed_set_min_size (EMACS_FIXED (FRAME_GTK_WIDGET (f)),
1297 size_hints.min_width,
1298 size_hints.min_height);
1299#endif
1300
1301 /* These currently have a one to one mapping with the X values, but I 1289 /* These currently have a one to one mapping with the X values, but I
1302 don't think we should rely on that. */ 1290 don't think we should rely on that. */
1303 hint_flags |= GDK_HINT_WIN_GRAVITY; 1291 hint_flags |= GDK_HINT_WIN_GRAVITY;
@@ -1336,7 +1324,7 @@ x_wm_set_size_hint (FRAME_PTR f, long int flags, int user_position)
1336 { 1324 {
1337 BLOCK_INPUT; 1325 BLOCK_INPUT;
1338 gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 1326 gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
1339 NULL, &size_hints, hint_flags); 1327 NULL, &size_hints, hint_flags);
1340 f->output_data.x->size_hints = size_hints; 1328 f->output_data.x->size_hints = size_hints;
1341 f->output_data.x->hint_flags = hint_flags; 1329 f->output_data.x->hint_flags = hint_flags;
1342 UNBLOCK_INPUT; 1330 UNBLOCK_INPUT;