diff options
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 214 |
1 files changed, 170 insertions, 44 deletions
diff --git a/src/xterm.c b/src/xterm.c index abceefb1b0e..555af2b536c 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -215,7 +215,7 @@ enum xembed_message | |||
| 215 | }; | 215 | }; |
| 216 | 216 | ||
| 217 | static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); | 217 | static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); |
| 218 | static void x_set_window_size_1 (struct frame *, bool, int, int, bool); | 218 | static void x_set_window_size_1 (struct frame *, bool, int, int); |
| 219 | static void x_raise_frame (struct frame *); | 219 | static void x_raise_frame (struct frame *); |
| 220 | static void x_lower_frame (struct frame *); | 220 | static void x_lower_frame (struct frame *); |
| 221 | static const XColor *x_color_cells (Display *, int *); | 221 | static const XColor *x_color_cells (Display *, int *); |
| @@ -6585,6 +6585,10 @@ x_net_wm_state (struct frame *f, Window window) | |||
| 6585 | break; | 6585 | break; |
| 6586 | } | 6586 | } |
| 6587 | 6587 | ||
| 6588 | frame_size_history_add | ||
| 6589 | (f, Qx_net_wm_state, 0, 0, | ||
| 6590 | list2 (get_frame_param (f, Qfullscreen), lval)); | ||
| 6591 | |||
| 6588 | store_frame_param (f, Qfullscreen, lval); | 6592 | store_frame_param (f, Qfullscreen, lval); |
| 6589 | /** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ | 6593 | /** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ |
| 6590 | } | 6594 | } |
| @@ -9242,30 +9246,78 @@ do_ewmh_fullscreen (struct frame *f) | |||
| 9242 | None); | 9246 | None); |
| 9243 | break; | 9247 | break; |
| 9244 | case FULLSCREEN_WIDTH: | 9248 | case FULLSCREEN_WIDTH: |
| 9245 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT | 9249 | if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) |
| 9246 | || cur == FULLSCREEN_MAXIMIZED) | 9250 | { |
| 9247 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | 9251 | set_wm_state (frame, false, |
| 9248 | dpyinfo->Xatom_net_wm_state_maximized_vert); | 9252 | dpyinfo->Xatom_net_wm_state_maximized_horz, |
| 9249 | if (cur != FULLSCREEN_MAXIMIZED) | 9253 | dpyinfo->Xatom_net_wm_state_maximized_vert); |
| 9250 | set_wm_state (frame, true, | 9254 | set_wm_state (frame, true, |
| 9251 | dpyinfo->Xatom_net_wm_state_maximized_horz, None); | 9255 | dpyinfo->Xatom_net_wm_state_maximized_horz, None); |
| 9256 | } | ||
| 9257 | else | ||
| 9258 | { | ||
| 9259 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT | ||
| 9260 | || cur == FULLSCREEN_MAXIMIZED) | ||
| 9261 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | ||
| 9262 | dpyinfo->Xatom_net_wm_state_maximized_vert); | ||
| 9263 | if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) | ||
| 9264 | set_wm_state (frame, true, | ||
| 9265 | dpyinfo->Xatom_net_wm_state_maximized_horz, None); | ||
| 9266 | } | ||
| 9252 | break; | 9267 | break; |
| 9253 | case FULLSCREEN_HEIGHT: | 9268 | case FULLSCREEN_HEIGHT: |
| 9254 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH | 9269 | if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) |
| 9255 | || cur == FULLSCREEN_MAXIMIZED) | 9270 | { |
| 9256 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | 9271 | set_wm_state (frame, false, |
| 9257 | dpyinfo->Xatom_net_wm_state_maximized_horz); | 9272 | dpyinfo->Xatom_net_wm_state_maximized_horz, |
| 9258 | if (cur != FULLSCREEN_MAXIMIZED) | 9273 | dpyinfo->Xatom_net_wm_state_maximized_vert); |
| 9259 | set_wm_state (frame, true, | 9274 | set_wm_state (frame, true, |
| 9260 | dpyinfo->Xatom_net_wm_state_maximized_vert, None); | 9275 | dpyinfo->Xatom_net_wm_state_maximized_vert, None); |
| 9276 | } | ||
| 9277 | else | ||
| 9278 | { | ||
| 9279 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH | ||
| 9280 | || cur == FULLSCREEN_MAXIMIZED) | ||
| 9281 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | ||
| 9282 | dpyinfo->Xatom_net_wm_state_maximized_horz); | ||
| 9283 | if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) | ||
| 9284 | set_wm_state (frame, true, | ||
| 9285 | dpyinfo->Xatom_net_wm_state_maximized_vert, None); | ||
| 9286 | } | ||
| 9261 | break; | 9287 | break; |
| 9262 | case FULLSCREEN_MAXIMIZED: | 9288 | case FULLSCREEN_MAXIMIZED: |
| 9263 | if (cur == FULLSCREEN_BOTH) | 9289 | if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH) |
| 9264 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | 9290 | { |
| 9265 | None); | 9291 | set_wm_state (frame, false, |
| 9266 | set_wm_state (frame, true, | 9292 | dpyinfo->Xatom_net_wm_state_maximized_horz, None); |
| 9267 | dpyinfo->Xatom_net_wm_state_maximized_horz, | 9293 | set_wm_state (frame, true, |
| 9268 | dpyinfo->Xatom_net_wm_state_maximized_vert); | 9294 | dpyinfo->Xatom_net_wm_state_maximized_horz, |
| 9295 | dpyinfo->Xatom_net_wm_state_maximized_vert); | ||
| 9296 | } | ||
| 9297 | else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT) | ||
| 9298 | { | ||
| 9299 | set_wm_state (frame, false, | ||
| 9300 | dpyinfo->Xatom_net_wm_state_maximized_vert, None); | ||
| 9301 | set_wm_state (frame, true, | ||
| 9302 | dpyinfo->Xatom_net_wm_state_maximized_horz, | ||
| 9303 | dpyinfo->Xatom_net_wm_state_maximized_vert); | ||
| 9304 | } | ||
| 9305 | else | ||
| 9306 | { | ||
| 9307 | if (cur == FULLSCREEN_BOTH) | ||
| 9308 | set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, | ||
| 9309 | None); | ||
| 9310 | else if (cur == FULLSCREEN_HEIGHT) | ||
| 9311 | set_wm_state (frame, true, | ||
| 9312 | dpyinfo->Xatom_net_wm_state_maximized_horz, None); | ||
| 9313 | else if (cur == FULLSCREEN_WIDTH) | ||
| 9314 | set_wm_state (frame, true, None, | ||
| 9315 | dpyinfo->Xatom_net_wm_state_maximized_vert); | ||
| 9316 | else | ||
| 9317 | set_wm_state (frame, true, | ||
| 9318 | dpyinfo->Xatom_net_wm_state_maximized_horz, | ||
| 9319 | dpyinfo->Xatom_net_wm_state_maximized_vert); | ||
| 9320 | } | ||
| 9269 | break; | 9321 | break; |
| 9270 | case FULLSCREEN_NONE: | 9322 | case FULLSCREEN_NONE: |
| 9271 | if (cur == FULLSCREEN_BOTH) | 9323 | if (cur == FULLSCREEN_BOTH) |
| @@ -9322,6 +9374,10 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event) | |||
| 9322 | break; | 9374 | break; |
| 9323 | } | 9375 | } |
| 9324 | 9376 | ||
| 9377 | frame_size_history_add | ||
| 9378 | (f, Qx_handle_net_wm_state, 0, 0, | ||
| 9379 | list2 (get_frame_param (f, Qfullscreen), lval)); | ||
| 9380 | |||
| 9325 | store_frame_param (f, Qfullscreen, lval); | 9381 | store_frame_param (f, Qfullscreen, lval); |
| 9326 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); | 9382 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); |
| 9327 | 9383 | ||
| @@ -9358,13 +9414,26 @@ x_check_fullscreen (struct frame *f) | |||
| 9358 | break; | 9414 | break; |
| 9359 | case FULLSCREEN_WIDTH: | 9415 | case FULLSCREEN_WIDTH: |
| 9360 | width = x_display_pixel_width (dpyinfo); | 9416 | width = x_display_pixel_width (dpyinfo); |
| 9361 | break; | 9417 | height = height + FRAME_MENUBAR_HEIGHT (f); |
| 9418 | break; | ||
| 9362 | case FULLSCREEN_HEIGHT: | 9419 | case FULLSCREEN_HEIGHT: |
| 9363 | height = x_display_pixel_height (dpyinfo); | 9420 | height = x_display_pixel_height (dpyinfo); |
| 9364 | } | 9421 | } |
| 9365 | 9422 | ||
| 9423 | frame_size_history_add | ||
| 9424 | (f, Qx_check_fullscreen, width, height, Qnil); | ||
| 9425 | |||
| 9366 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | 9426 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), |
| 9367 | width, height); | 9427 | width, height); |
| 9428 | |||
| 9429 | if (FRAME_VISIBLE_P (f)) | ||
| 9430 | x_wait_for_event (f, ConfigureNotify); | ||
| 9431 | else | ||
| 9432 | { | ||
| 9433 | change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f), | ||
| 9434 | false, true, false, true); | ||
| 9435 | x_sync (f); | ||
| 9436 | } | ||
| 9368 | } | 9437 | } |
| 9369 | } | 9438 | } |
| 9370 | 9439 | ||
| @@ -9505,21 +9574,57 @@ x_wait_for_event (struct frame *f, int eventtype) | |||
| 9505 | 9574 | ||
| 9506 | static void | 9575 | static void |
| 9507 | x_set_window_size_1 (struct frame *f, bool change_gravity, | 9576 | x_set_window_size_1 (struct frame *f, bool change_gravity, |
| 9508 | int width, int height, bool pixelwise) | 9577 | int width, int height) |
| 9509 | { | 9578 | { |
| 9510 | int pixelwidth, pixelheight; | 9579 | int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); |
| 9511 | 9580 | int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); | |
| 9512 | pixelwidth = (pixelwise | 9581 | int old_width = FRAME_PIXEL_WIDTH (f); |
| 9513 | ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) | 9582 | int old_height = FRAME_PIXEL_HEIGHT (f); |
| 9514 | : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); | 9583 | Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); |
| 9515 | pixelheight = ((pixelwise | ||
| 9516 | ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) | ||
| 9517 | : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); | ||
| 9518 | 9584 | ||
| 9519 | if (change_gravity) f->win_gravity = NorthWestGravity; | 9585 | if (change_gravity) f->win_gravity = NorthWestGravity; |
| 9520 | x_wm_set_size_hint (f, 0, false); | 9586 | x_wm_set_size_hint (f, 0, false); |
| 9521 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | 9587 | |
| 9522 | pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); | 9588 | /* When the frame is fullheight and we only want to change the width |
| 9589 | or it is fullwidth and we only want to change the height we should | ||
| 9590 | be able to preserve the fullscreen property. However, due to the | ||
| 9591 | fact that we have to send a resize request anyway, the window | ||
| 9592 | manager will abolish it. At least the respective size should | ||
| 9593 | remain unchanged but giving the frame back its normal size will | ||
| 9594 | be broken ... */ | ||
| 9595 | if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f)) | ||
| 9596 | { | ||
| 9597 | frame_size_history_add | ||
| 9598 | (f, Qxg_frame_set_char_size_1, width, height, | ||
| 9599 | list2 (make_number (old_height), | ||
| 9600 | make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f)))); | ||
| 9601 | |||
| 9602 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 9603 | old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f)); | ||
| 9604 | } | ||
| 9605 | else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) | ||
| 9606 | { | ||
| 9607 | frame_size_history_add | ||
| 9608 | (f, Qxg_frame_set_char_size_2, width, height, | ||
| 9609 | list2 (make_number (old_width), make_number (pixelwidth))); | ||
| 9610 | |||
| 9611 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 9612 | pixelwidth, old_height); | ||
| 9613 | } | ||
| 9614 | |||
| 9615 | else | ||
| 9616 | { | ||
| 9617 | frame_size_history_add | ||
| 9618 | (f, Qxg_frame_set_char_size_3, width, height, | ||
| 9619 | list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), | ||
| 9620 | make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) | ||
| 9621 | + FRAME_MENUBAR_HEIGHT (f)))); | ||
| 9622 | |||
| 9623 | XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), | ||
| 9624 | pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); | ||
| 9625 | fullscreen = Qnil; | ||
| 9626 | } | ||
| 9627 | |||
| 9523 | 9628 | ||
| 9524 | 9629 | ||
| 9525 | /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to | 9630 | /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to |
| @@ -9546,7 +9651,16 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, | |||
| 9546 | not right if the frame is visible. Instead wait (with timeout) | 9651 | not right if the frame is visible. Instead wait (with timeout) |
| 9547 | for the ConfigureNotify. */ | 9652 | for the ConfigureNotify. */ |
| 9548 | if (FRAME_VISIBLE_P (f)) | 9653 | if (FRAME_VISIBLE_P (f)) |
| 9549 | x_wait_for_event (f, ConfigureNotify); | 9654 | { |
| 9655 | x_wait_for_event (f, ConfigureNotify); | ||
| 9656 | |||
| 9657 | if (!NILP (fullscreen)) | ||
| 9658 | /* Try to restore fullscreen state. */ | ||
| 9659 | { | ||
| 9660 | store_frame_param (f, Qfullscreen, fullscreen); | ||
| 9661 | x_set_fullscreen (f, fullscreen, fullscreen); | ||
| 9662 | } | ||
| 9663 | } | ||
| 9550 | else | 9664 | else |
| 9551 | { | 9665 | { |
| 9552 | change_frame_size (f, width, height, false, true, false, true); | 9666 | change_frame_size (f, width, height, false, true, false, true); |
| @@ -9593,20 +9707,21 @@ x_set_window_size (struct frame *f, bool change_gravity, | |||
| 9593 | } | 9707 | } |
| 9594 | #endif | 9708 | #endif |
| 9595 | 9709 | ||
| 9710 | /* Pixelize width and height, if necessary. */ | ||
| 9711 | if (! pixelwise) | ||
| 9712 | { | ||
| 9713 | width = width * FRAME_COLUMN_WIDTH (f); | ||
| 9714 | height = height * FRAME_LINE_HEIGHT (f); | ||
| 9715 | } | ||
| 9716 | |||
| 9596 | #ifdef USE_GTK | 9717 | #ifdef USE_GTK |
| 9597 | if (FRAME_GTK_WIDGET (f)) | 9718 | if (FRAME_GTK_WIDGET (f)) |
| 9598 | if (! pixelwise) | 9719 | xg_frame_set_char_size (f, width, height); |
| 9599 | xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f), | ||
| 9600 | height * FRAME_LINE_HEIGHT (f)); | ||
| 9601 | else | ||
| 9602 | xg_frame_set_char_size (f, width, height); | ||
| 9603 | else | 9720 | else |
| 9604 | x_set_window_size_1 (f, change_gravity, width, height, pixelwise); | 9721 | x_set_window_size_1 (f, change_gravity, width, height); |
| 9605 | #else /* not USE_GTK */ | 9722 | #else /* not USE_GTK */ |
| 9606 | 9723 | x_set_window_size_1 (f, change_gravity, width, height); | |
| 9607 | x_set_window_size_1 (f, change_gravity, width, height, pixelwise); | ||
| 9608 | x_clear_under_internal_border (f); | 9724 | x_clear_under_internal_border (f); |
| 9609 | |||
| 9610 | #endif /* not USE_GTK */ | 9725 | #endif /* not USE_GTK */ |
| 9611 | 9726 | ||
| 9612 | /* If cursor was outside the new size, mark it as off. */ | 9727 | /* If cursor was outside the new size, mark it as off. */ |
| @@ -11617,4 +11732,15 @@ default is nil, which is the same as `super'. */); | |||
| 11617 | make_float (DEFAULT_REHASH_SIZE), | 11732 | make_float (DEFAULT_REHASH_SIZE), |
| 11618 | make_float (DEFAULT_REHASH_THRESHOLD), | 11733 | make_float (DEFAULT_REHASH_THRESHOLD), |
| 11619 | Qnil); | 11734 | Qnil); |
| 11735 | |||
| 11736 | DEFVAR_BOOL ("x-frame-normalize-before-maximize", | ||
| 11737 | x_frame_normalize_before_maximize, | ||
| 11738 | doc: /* Non-nil means normalize frame before maximizing. | ||
| 11739 | If this variable is t, Emacs asks the window manager to give the frame | ||
| 11740 | intermediately its normal size whenever changing from a full-height or | ||
| 11741 | full-width state to the fully maximized one and vice versa. | ||
| 11742 | |||
| 11743 | Set this variable only if your window manager cannot handle the | ||
| 11744 | transition between the various maximization states. */); | ||
| 11745 | x_frame_normalize_before_maximize = false; | ||
| 11620 | } | 11746 | } |