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 }; static bool x_alloc_nearest_color_1 (Display *, Colormap, XColor *); -static void x_set_window_size_1 (struct frame *, bool, int, int, bool); +static void x_set_window_size_1 (struct frame *, bool, int, int); static void x_raise_frame (struct frame *); static void x_lower_frame (struct frame *); static const XColor *x_color_cells (Display *, int *); @@ -6585,6 +6585,10 @@ x_net_wm_state (struct frame *f, Window window) break; } + frame_size_history_add + (f, Qx_net_wm_state, 0, 0, + list2 (get_frame_param (f, Qfullscreen), lval)); + store_frame_param (f, Qfullscreen, lval); /** store_frame_param (f, Qsticky, sticky ? Qt : Qnil); **/ } @@ -9242,30 +9246,78 @@ do_ewmh_fullscreen (struct frame *f) None); break; case FULLSCREEN_WIDTH: - if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT - || cur == FULLSCREEN_MAXIMIZED) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - dpyinfo->Xatom_net_wm_state_maximized_vert); - if (cur != FULLSCREEN_MAXIMIZED) - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_horz, None); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + } + else + { + if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT + || cur == FULLSCREEN_MAXIMIZED) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + dpyinfo->Xatom_net_wm_state_maximized_vert); + if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + } break; case FULLSCREEN_HEIGHT: - if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH - || cur == FULLSCREEN_MAXIMIZED) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - dpyinfo->Xatom_net_wm_state_maximized_horz); - if (cur != FULLSCREEN_MAXIMIZED) - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_vert, None); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_MAXIMIZED) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + } + else + { + if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH + || cur == FULLSCREEN_MAXIMIZED) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + dpyinfo->Xatom_net_wm_state_maximized_horz); + if (cur != FULLSCREEN_MAXIMIZED || x_frame_normalize_before_maximize) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + } break; case FULLSCREEN_MAXIMIZED: - if (cur == FULLSCREEN_BOTH) - set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, - None); - set_wm_state (frame, true, - dpyinfo->Xatom_net_wm_state_maximized_horz, - dpyinfo->Xatom_net_wm_state_maximized_vert); + if (x_frame_normalize_before_maximize && cur == FULLSCREEN_WIDTH) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } + else if (x_frame_normalize_before_maximize && cur == FULLSCREEN_HEIGHT) + { + set_wm_state (frame, false, + dpyinfo->Xatom_net_wm_state_maximized_vert, None); + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } + else + { + if (cur == FULLSCREEN_BOTH) + set_wm_state (frame, false, dpyinfo->Xatom_net_wm_state_fullscreen, + None); + else if (cur == FULLSCREEN_HEIGHT) + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, None); + else if (cur == FULLSCREEN_WIDTH) + set_wm_state (frame, true, None, + dpyinfo->Xatom_net_wm_state_maximized_vert); + else + set_wm_state (frame, true, + dpyinfo->Xatom_net_wm_state_maximized_horz, + dpyinfo->Xatom_net_wm_state_maximized_vert); + } break; case FULLSCREEN_NONE: if (cur == FULLSCREEN_BOTH) @@ -9322,6 +9374,10 @@ x_handle_net_wm_state (struct frame *f, const XPropertyEvent *event) break; } + frame_size_history_add + (f, Qx_handle_net_wm_state, 0, 0, + list2 (get_frame_param (f, Qfullscreen), lval)); + store_frame_param (f, Qfullscreen, lval); store_frame_param (f, Qsticky, sticky ? Qt : Qnil); @@ -9358,13 +9414,26 @@ x_check_fullscreen (struct frame *f) break; case FULLSCREEN_WIDTH: width = x_display_pixel_width (dpyinfo); - break; + height = height + FRAME_MENUBAR_HEIGHT (f); + break; case FULLSCREEN_HEIGHT: height = x_display_pixel_height (dpyinfo); } + frame_size_history_add + (f, Qx_check_fullscreen, width, height, Qnil); + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - width, height); + width, height); + + if (FRAME_VISIBLE_P (f)) + x_wait_for_event (f, ConfigureNotify); + else + { + change_frame_size (f, width, height - FRAME_MENUBAR_HEIGHT (f), + false, true, false, true); + x_sync (f); + } } } @@ -9505,21 +9574,57 @@ x_wait_for_event (struct frame *f, int eventtype) static void x_set_window_size_1 (struct frame *f, bool change_gravity, - int width, int height, bool pixelwise) + int width, int height) { - int pixelwidth, pixelheight; - - pixelwidth = (pixelwise - ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) - : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); - pixelheight = ((pixelwise - ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) - : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); + int pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); + int pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); + int old_width = FRAME_PIXEL_WIDTH (f); + int old_height = FRAME_PIXEL_HEIGHT (f); + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); if (change_gravity) f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, 0, false); - XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + + /* When the frame is fullheight and we only want to change the width + or it is fullwidth and we only want to change the height we should + be able to preserve the fullscreen property. However, due to the + fact that we have to send a resize request anyway, the window + manager will abolish it. At least the respective size should + remain unchanged but giving the frame back its normal size will + be broken ... */ + if (EQ (fullscreen, Qfullwidth) && width == FRAME_TEXT_WIDTH (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_1, width, height, + list2 (make_number (old_height), + make_number (pixelheight + FRAME_MENUBAR_HEIGHT (f)))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + old_width, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + } + else if (EQ (fullscreen, Qfullheight) && height == FRAME_TEXT_HEIGHT (f)) + { + frame_size_history_add + (f, Qxg_frame_set_char_size_2, width, height, + list2 (make_number (old_width), make_number (pixelwidth))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + pixelwidth, old_height); + } + + else + { + frame_size_history_add + (f, Qxg_frame_set_char_size_3, width, height, + list2 (make_number (pixelwidth + FRAME_TOOLBAR_WIDTH (f)), + make_number (pixelheight + FRAME_TOOLBAR_HEIGHT (f) + + FRAME_MENUBAR_HEIGHT (f)))); + + XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + pixelwidth, pixelheight + FRAME_MENUBAR_HEIGHT (f)); + fullscreen = Qnil; + } + /* 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, not right if the frame is visible. Instead wait (with timeout) for the ConfigureNotify. */ if (FRAME_VISIBLE_P (f)) - x_wait_for_event (f, ConfigureNotify); + { + x_wait_for_event (f, ConfigureNotify); + + if (!NILP (fullscreen)) + /* Try to restore fullscreen state. */ + { + store_frame_param (f, Qfullscreen, fullscreen); + x_set_fullscreen (f, fullscreen, fullscreen); + } + } else { change_frame_size (f, width, height, false, true, false, true); @@ -9593,20 +9707,21 @@ x_set_window_size (struct frame *f, bool change_gravity, } #endif + /* Pixelize width and height, if necessary. */ + if (! pixelwise) + { + width = width * FRAME_COLUMN_WIDTH (f); + height = height * FRAME_LINE_HEIGHT (f); + } + #ifdef USE_GTK if (FRAME_GTK_WIDGET (f)) - if (! pixelwise) - xg_frame_set_char_size (f, width * FRAME_COLUMN_WIDTH (f), - height * FRAME_LINE_HEIGHT (f)); - else - xg_frame_set_char_size (f, width, height); + xg_frame_set_char_size (f, width, height); else - x_set_window_size_1 (f, change_gravity, width, height, pixelwise); + x_set_window_size_1 (f, change_gravity, width, height); #else /* not USE_GTK */ - - x_set_window_size_1 (f, change_gravity, width, height, pixelwise); + x_set_window_size_1 (f, change_gravity, width, height); x_clear_under_internal_border (f); - #endif /* not USE_GTK */ /* If cursor was outside the new size, mark it as off. */ @@ -11617,4 +11732,15 @@ default is nil, which is the same as `super'. */); make_float (DEFAULT_REHASH_SIZE), make_float (DEFAULT_REHASH_THRESHOLD), Qnil); + + DEFVAR_BOOL ("x-frame-normalize-before-maximize", + x_frame_normalize_before_maximize, + doc: /* Non-nil means normalize frame before maximizing. +If this variable is t, Emacs asks the window manager to give the frame +intermediately its normal size whenever changing from a full-height or +full-width state to the fully maximized one and vice versa. + +Set this variable only if your window manager cannot handle the +transition between the various maximization states. */); + x_frame_normalize_before_maximize = false; } |