diff options
| author | Jan Djärv | 2011-06-26 20:47:07 +0200 |
|---|---|---|
| committer | Jan Djärv | 2011-06-26 20:47:07 +0200 |
| commit | c7e73be5f7c8f5d24757ace235bc622a9a7fdcd0 (patch) | |
| tree | d32a59317249eaa9958627f1a6a3584db670ba46 | |
| parent | 247f696e50461a50306bc77d3683007bd06e8ba7 (diff) | |
| download | emacs-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/ChangeLog | 23 | ||||
| -rw-r--r-- | src/emacsgtkfixed.c | 101 | ||||
| -rw-r--r-- | src/emacsgtkfixed.h | 8 | ||||
| -rw-r--r-- | src/gtkutil.c | 16 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-06-26 Eli Zaretskii <eliz@gnu.org> | 24 | 2011-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. |
| 2 | This file is only use when compiling with Gtk+ 3. | ||
| 2 | 3 | ||
| 3 | Copyright (C) 2011 Free Software Foundation, Inc. | 4 | Copyright (C) 2011 Free Software Foundation, Inc. |
| 4 | 5 | ||
| @@ -17,12 +18,19 @@ GNU General Public License for more details. | |||
| 17 | You should have received a copy of the GNU General Public License | 18 | You should have received a copy of the GNU General Public License |
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | 19 | along 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 | ||
| 23 | struct _EmacsFixedPrivate | 31 | struct _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 | */ |
| 72 | GtkWidget* | 80 | GtkWidget* |
| 73 | emacs_fixed_new (void) | 81 | emacs_fixed_new (struct frame *f) |
| 74 | { | ||
| 75 | return g_object_new (EMACS_TYPE_FIXED, NULL); | ||
| 76 | } | ||
| 77 | |||
| 78 | static GtkWidgetClass * | ||
| 79 | get_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 | ||
| 86 | static void | 89 | static 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 | ||
| 98 | static void | 101 | static 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 | |||
| 110 | void | 118 | void |
| 111 | emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height) | 119 | XSetWMSizeHints(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 | |||
| 162 | void | ||
| 163 | XSetWMNormalHints (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. |
| 2 | This file is only use when compiling with Gtk+ 3. | ||
| 2 | 3 | ||
| 3 | Copyright (C) 2011 Free Software Foundation, Inc. | 4 | Copyright (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 | ||
| 25 | G_BEGIN_DECLS | 26 | G_BEGIN_DECLS |
| 26 | 27 | ||
| 28 | struct 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 | ||
| 52 | extern GtkWidget *emacs_fixed_new (void); | 55 | extern GtkWidget *emacs_fixed_new (struct frame *f); |
| 53 | extern void emacs_fixed_set_min_size (EmacsFixed *widget, int width, int height); | ||
| 54 | extern GType emacs_fixed_get_type (void); | 56 | extern GType emacs_fixed_get_type (void); |
| 55 | 57 | ||
| 56 | G_END_DECLS | 58 | G_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; |