diff options
| author | Po Lu | 2022-10-12 15:07:49 +0800 |
|---|---|---|
| committer | Po Lu | 2022-10-12 15:08:01 +0800 |
| commit | 2953d89d74ebfe6a6bcbe0d25a60a845acad0e13 (patch) | |
| tree | af5220d41ea686ac0df84743acfc1db31668a875 /src | |
| parent | c22e85715e47e371fda1af420f54e3840978b81f (diff) | |
| download | emacs-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.c | 42 | ||||
| -rw-r--r-- | src/widget.h | 2 | ||||
| -rw-r--r-- | src/widgetprv.h | 3 | ||||
| -rw-r--r-- | src/xterm.c | 19 |
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 | ||
| 198 | static Widget | 198 | static WMShellWidget |
| 199 | get_wm_shell (Widget w) | 199 | get_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 | ||
| 272 | static void | 272 | static bool |
| 273 | update_wm_hints (Widget wmshell, EmacsFrame ew) | 273 | update_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 | ||
| 312 | void | 320 | bool |
| 313 | widget_update_wm_size_hints (Widget widget, Widget frame) | 321 | widget_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 | ||
| 318 | static void | 326 | static 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 */ |
| 98 | void EmacsFrameSetCharSize (Widget, int, int); | 98 | void EmacsFrameSetCharSize (Widget, int, int); |
| 99 | void widget_store_internal_border (Widget widget); | 99 | void widget_store_internal_border (Widget widget); |
| 100 | void widget_update_wm_size_hints (Widget widget, Widget frame); | 100 | bool 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; |