aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-10-12 15:07:49 +0800
committerPo Lu2022-10-12 15:08:01 +0800
commit2953d89d74ebfe6a6bcbe0d25a60a845acad0e13 (patch)
treeaf5220d41ea686ac0df84743acfc1db31668a875 /src
parentc22e85715e47e371fda1af420f54e3840978b81f (diff)
downloademacs-2953d89d74ebfe6a6bcbe0d25a60a845acad0e13.tar.gz
emacs-2953d89d74ebfe6a6bcbe0d25a60a845acad0e13.zip
Stop relying on Xt hack to set window manager hints
* src/widget.c (get_wm_shell): Return WMShellWidget. (update_wm_hints, widget_update_wm_size_hints): Return whether or not size hints changed. * src/widget.h: Delete `size_switch'. * src/widgetprv.h (EmacsFramePart): Likewise. * src/xterm.c (x_wm_set_size_hint): Set size hints the usual way if Xt did not set them. (bug#58412)
Diffstat (limited to 'src')
-rw-r--r--src/widget.c42
-rw-r--r--src/widget.h2
-rw-r--r--src/widgetprv.h3
-rw-r--r--src/xterm.c19
4 files changed, 40 insertions, 26 deletions
diff --git a/src/widget.c b/src/widget.c
index 5a75cdaca8e..aaab33b6d8e 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -195,7 +195,7 @@ round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height,
195 out_width, out_height); 195 out_width, out_height);
196} 196}
197 197
198static Widget 198static WMShellWidget
199get_wm_shell (Widget w) 199get_wm_shell (Widget w)
200{ 200{
201 Widget wmshell; 201 Widget wmshell;
@@ -204,7 +204,7 @@ get_wm_shell (Widget w)
204 wmshell && !XtIsWMShell (wmshell); 204 wmshell && !XtIsWMShell (wmshell);
205 wmshell = XtParent (wmshell)); 205 wmshell = XtParent (wmshell));
206 206
207 return wmshell; 207 return (WMShellWidget) wmshell;
208} 208}
209 209
210#if 0 /* Currently not used. */ 210#if 0 /* Currently not used. */
@@ -269,8 +269,8 @@ set_frame_size (EmacsFrame ew)
269 (f, build_string ("set_frame_size")); 269 (f, build_string ("set_frame_size"));
270} 270}
271 271
272static void 272static bool
273update_wm_hints (Widget wmshell, EmacsFrame ew) 273update_wm_hints (WMShellWidget wmshell, EmacsFrame ew)
274{ 274{
275 int cw; 275 int cw;
276 int ch; 276 int ch;
@@ -280,6 +280,12 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
280 int char_height; 280 int char_height;
281 int base_width; 281 int base_width;
282 int base_height; 282 int base_height;
283 char buffer[sizeof wmshell->wm.size_hints];
284 char *hints_ptr;
285
286 /* Copy the old size hints to the buffer. */
287 memcpy (buffer, &wmshell->wm.size_hints,
288 sizeof wmshell->wm.size_hints);
283 289
284 pixel_to_char_size (ew, ew->core.width, ew->core.height, 290 pixel_to_char_size (ew, ew->core.width, ew->core.height,
285 &char_width, &char_height); 291 &char_width, &char_height);
@@ -292,27 +298,29 @@ update_wm_hints (Widget wmshell, EmacsFrame ew)
292 base_height = (wmshell->core.height - ew->core.height 298 base_height = (wmshell->core.height - ew->core.height
293 + (rounded_height - (char_height * ch))); 299 + (rounded_height - (char_height * ch)));
294 300
295 /* Ensure that Xt actually sets window manager hint flags specified 301 XtVaSetValues ((Widget) wmshell,
296 by the caller by making sure XtNminWidth (a relatively harmless
297 resource) always changes each time this function is invoked. */
298 ew->emacs_frame.size_switch = !ew->emacs_frame.size_switch;
299
300 XtVaSetValues (wmshell,
301 XtNbaseWidth, (XtArgVal) base_width, 302 XtNbaseWidth, (XtArgVal) base_width,
302 XtNbaseHeight, (XtArgVal) base_height, 303 XtNbaseHeight, (XtArgVal) base_height,
303 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw), 304 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
304 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch), 305 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
305 XtNminWidth, (XtArgVal) (base_width 306 XtNminWidth, (XtArgVal) base_width,
306 + ew->emacs_frame.size_switch), 307 XtNminHeight, (XtArgVal) base_height,
307 XtNminHeight, (XtArgVal) (base_height
308 + ew->emacs_frame.size_switch),
309 NULL); 308 NULL);
309
310 /* Return if size hints really changed. If they did not, then Xt
311 probably didn't set them either (or take the flags into
312 account.) */
313 hints_ptr = (char *) &wmshell->wm.size_hints;
314
315 /* Skip flags, which is unsigned long. */
316 return memcmp (hints_ptr + sizeof (long), buffer + sizeof (long),
317 sizeof wmshell->wm.wm_hints - sizeof (long));
310} 318}
311 319
312void 320bool
313widget_update_wm_size_hints (Widget widget, Widget frame) 321widget_update_wm_size_hints (Widget widget, Widget frame)
314{ 322{
315 update_wm_hints (widget, (EmacsFrame) frame); 323 return update_wm_hints ((WMShellWidget) widget, (EmacsFrame) frame);
316} 324}
317 325
318static void 326static void
@@ -357,8 +365,6 @@ EmacsFrameInitialize (Widget request, Widget new,
357 exit (1); 365 exit (1);
358 } 366 }
359 367
360 ew->emacs_frame.size_switch = 1;
361
362 update_from_various_frame_slots (ew); 368 update_from_various_frame_slots (ew);
363 set_frame_size (ew); 369 set_frame_size (ew);
364} 370}
diff --git a/src/widget.h b/src/widget.h
index 2906d5ff9ec..cf83cb10781 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -97,6 +97,6 @@ extern struct _DisplayContext *display_context;
97/* Special entry points */ 97/* Special entry points */
98void EmacsFrameSetCharSize (Widget, int, int); 98void EmacsFrameSetCharSize (Widget, int, int);
99void widget_store_internal_border (Widget widget); 99void widget_store_internal_border (Widget widget);
100void widget_update_wm_size_hints (Widget widget, Widget frame); 100bool widget_update_wm_size_hints (Widget widget, Widget frame);
101 101
102#endif /* _EmacsFrame_h */ 102#endif /* _EmacsFrame_h */
diff --git a/src/widgetprv.h b/src/widgetprv.h
index fe960326b03..3a4d9206ffe 100644
--- a/src/widgetprv.h
+++ b/src/widgetprv.h
@@ -49,9 +49,6 @@ typedef struct {
49 49
50 Boolean visual_bell; /* flash instead of beep */ 50 Boolean visual_bell; /* flash instead of beep */
51 int bell_volume; /* how loud is beep */ 51 int bell_volume; /* how loud is beep */
52 int size_switch; /* hack to make setting size
53 hints work correctly */
54
55 /* private state */ 52 /* private state */
56 53
57} EmacsFramePart; 54} EmacsFramePart;
diff --git a/src/xterm.c b/src/xterm.c
index 9c34fce7c5b..9059ad7136e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -28006,6 +28006,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28006 Window window = FRAME_OUTER_WINDOW (f); 28006 Window window = FRAME_OUTER_WINDOW (f);
28007#ifdef USE_X_TOOLKIT 28007#ifdef USE_X_TOOLKIT
28008 WMShellWidget shell; 28008 WMShellWidget shell;
28009 bool hints_changed;
28009#endif 28010#endif
28010 28011
28011 if (!window) 28012 if (!window)
@@ -28032,8 +28033,9 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28032 shell->wm.size_hints.flags |= USPosition; 28033 shell->wm.size_hints.flags |= USPosition;
28033 } 28034 }
28034 28035
28035 widget_update_wm_size_hints (f->output_data.x->widget, 28036 hints_changed
28036 f->output_data.x->edit_widget); 28037 = widget_update_wm_size_hints (f->output_data.x->widget,
28038 f->output_data.x->edit_widget);
28037 28039
28038#ifdef USE_MOTIF 28040#ifdef USE_MOTIF
28039 /* Do this all over again for the benefit of Motif, which always 28041 /* Do this all over again for the benefit of Motif, which always
@@ -28046,6 +28048,7 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28046 shell->wm.size_hints.flags &= ~PPosition; 28048 shell->wm.size_hints.flags &= ~PPosition;
28047 shell->wm.size_hints.flags |= USPosition; 28049 shell->wm.size_hints.flags |= USPosition;
28048 } 28050 }
28051#endif
28049 28052
28050 /* Drill hints into Motif, since it keeps setting its own. */ 28053 /* Drill hints into Motif, since it keeps setting its own. */
28051 size_hints.flags = shell->wm.size_hints.flags; 28054 size_hints.flags = shell->wm.size_hints.flags;
@@ -28063,15 +28066,23 @@ x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
28063 size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y; 28066 size_hints.min_aspect.y = shell->wm.size_hints.min_aspect.y;
28064 size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x; 28067 size_hints.max_aspect.x = shell->wm.size_hints.max_aspect.x;
28065 size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y; 28068 size_hints.max_aspect.y = shell->wm.size_hints.max_aspect.y;
28066#ifdef HAVE_X11XTR6
28067 size_hints.base_width = shell->wm.base_width; 28069 size_hints.base_width = shell->wm.base_width;
28068 size_hints.base_height = shell->wm.base_height; 28070 size_hints.base_height = shell->wm.base_height;
28069 size_hints.win_gravity = shell->wm.win_gravity; 28071 size_hints.win_gravity = shell->wm.win_gravity;
28070#endif
28071 28072
28073#ifdef USE_MOTIF
28072 XSetWMNormalHints (XtDisplay (f->output_data.x->widget), 28074 XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
28073 XtWindow (f->output_data.x->widget), 28075 XtWindow (f->output_data.x->widget),
28074 &size_hints); 28076 &size_hints);
28077#else
28078 /* In many cases, widget_update_wm_size_hints will not have
28079 updated the size hints if only flags changed. When that
28080 happens, set the WM hints manually. */
28081
28082 if (!hints_changed)
28083 XSetWMNormalHints (XtDisplay (f->output_data.x->widget),
28084 XtWindow (f->output_data.x->widget),
28085 &size_hints);
28075#endif 28086#endif
28076 28087
28077 return; 28088 return;