aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c217
1 files changed, 89 insertions, 128 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 251c46c73cf..fb9d2388d6b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3344,8 +3344,6 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object
3344 enum scroll_bar_part *, 3344 enum scroll_bar_part *,
3345 Lisp_Object *, Lisp_Object *, 3345 Lisp_Object *, Lisp_Object *,
3346 Time *); 3346 Time *);
3347static void x_check_fullscreen (struct frame *);
3348
3349static void 3347static void
3350w32_define_cursor (Window window, Cursor cursor) 3348w32_define_cursor (Window window, Cursor cursor)
3351{ 3349{
@@ -4989,8 +4987,12 @@ w32_read_socket (struct terminal *terminal,
4989 sets the WAIT flag. */ 4987 sets the WAIT flag. */
4990 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam) 4988 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
4991 && (f->want_fullscreen & FULLSCREEN_WAIT)) 4989 && (f->want_fullscreen & FULLSCREEN_WAIT))
4992 w32fullscreen_hook (f); 4990 {
4993 x_check_fullscreen (f); 4991 /* Must set visibility right here since otherwise
4992 w32fullscreen_hook returns immediately. */
4993 SET_FRAME_VISIBLE (f, 1);
4994 w32fullscreen_hook (f);
4995 }
4994 } 4996 }
4995 check_visibility = 1; 4997 check_visibility = 1;
4996 break; 4998 break;
@@ -5269,11 +5271,18 @@ w32_read_socket (struct terminal *terminal,
5269 5271
5270 if (f) 5272 if (f)
5271 { 5273 {
5274 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
5275
5272 dpyinfo->n_cbits = msg.msg.wParam; 5276 dpyinfo->n_cbits = msg.msg.wParam;
5273 /* The new display could have a different resolution, in 5277 /* The new display could have a different resolution, in
5274 which case we must reconsider what fullscreen 5278 which case we must reconsider what fullscreen means.
5275 means. */ 5279 The following code is untested yet. */
5276 x_check_fullscreen (f); 5280 if (!NILP (fullscreen))
5281 {
5282 x_set_fullscreen (f, fullscreen, fullscreen);
5283 w32fullscreen_hook (f);
5284 }
5285
5277 DebPrint (("display change: %d %d\n", 5286 DebPrint (("display change: %d %d\n",
5278 (short) LOWORD (msg.msg.lParam), 5287 (short) LOWORD (msg.msg.lParam),
5279 (short) HIWORD (msg.msg.lParam))); 5288 (short) HIWORD (msg.msg.lParam)));
@@ -5959,75 +5968,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff,
5959 unblock_input (); 5968 unblock_input ();
5960} 5969}
5961 5970
5962/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
5963 wanted positions of the WM window (not Emacs window).
5964 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
5965 window (FRAME_X_WINDOW).
5966 */
5967
5968static void
5969x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos)
5970{
5971 int newwidth = FRAME_COLS (f);
5972 int newheight = FRAME_LINES (f);
5973 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
5974
5975 *top_pos = f->top_pos;
5976 *left_pos = f->left_pos;
5977
5978 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
5979 {
5980 int ph;
5981
5982 ph = x_display_pixel_height (dpyinfo);
5983 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5984 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
5985 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
5986 *top_pos = 0;
5987 }
5988
5989 if (f->want_fullscreen & FULLSCREEN_WIDTH)
5990 {
5991 int pw;
5992
5993 pw = x_display_pixel_width (dpyinfo);
5994 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5995 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
5996 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
5997 *left_pos = 0;
5998 }
5999
6000 *width = newwidth;
6001 *height = newheight;
6002}
6003
6004/* Check if we need to resize the frame due to a fullscreen request.
6005 If so needed, resize the frame. */
6006static void
6007x_check_fullscreen (struct frame *f)
6008{
6009 if (f->want_fullscreen & FULLSCREEN_BOTH)
6010 {
6011 int width, height, ign;
6012
6013 x_real_positions (f, &f->left_pos, &f->top_pos);
6014
6015 x_fullscreen_adjust (f, &width, &height, &ign, &ign);
6016
6017 /* We do not need to move the window, it shall be taken care of
6018 when setting WM manager hints. */
6019 if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
6020 {
6021 change_frame_size (f, width, height, 0, 1, 0, 0);
6022 SET_FRAME_GARBAGED (f);
6023 cancel_mouse_face (f);
6024
6025 /* Wait for the change of frame size to occur. */
6026 f->want_fullscreen |= FULLSCREEN_WAIT;
6027 }
6028 }
6029}
6030
6031static void 5971static void
6032w32fullscreen_hook (struct frame *f) 5972w32fullscreen_hook (struct frame *f)
6033{ 5973{
@@ -6074,6 +6014,10 @@ w32fullscreen_hook (struct frame *f)
6074 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6014 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6075 rect.right - rect.left, rect.bottom - rect.top, 6015 rect.right - rect.left, rect.bottom - rect.top,
6076 SWP_NOOWNERZORDER | SWP_FRAMECHANGED); 6016 SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
6017 change_frame_size
6018 (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left),
6019 FRAME_PIXEL_TO_TEXT_HEIGHT (f, rect.bottom - rect.top),
6020 0, 1, 0, 1);
6077 } 6021 }
6078 else 6022 else
6079 { 6023 {
@@ -6082,10 +6026,39 @@ w32fullscreen_hook (struct frame *f)
6082 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); 6026 FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
6083 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, 6027 SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
6084 rect.right - rect.left, rect.bottom - rect.top, 0); 6028 rect.right - rect.left, rect.bottom - rect.top, 0);
6029
6030 if (f->want_fullscreen == FULLSCREEN_WIDTH)
6031 {
6032 int border_width = GetSystemMetrics (SM_CXFRAME);
6033
6034 change_frame_size
6035 (f, (FRAME_PIXEL_TO_TEXT_WIDTH
6036 (f, rect.right - rect.left - 2 * border_width)),
6037 0, 0, 1, 0, 1);
6038 }
6039 else
6040 {
6041 int border_height = GetSystemMetrics (SM_CYFRAME);
6042 /* Won't work for wrapped menu bar. */
6043 int menu_bar_height = GetSystemMetrics (SM_CYMENU);
6044 int title_height = GetSystemMetrics (SM_CYCAPTION);
6045
6046 change_frame_size
6047 (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT
6048 (f, rect.bottom - rect.top - 2 * border_height
6049 - title_height - menu_bar_height)),
6050 0, 1, 0, 1);
6051 }
6085 } 6052 }
6086 6053
6087 f->want_fullscreen = FULLSCREEN_NONE; 6054 f->want_fullscreen = FULLSCREEN_NONE;
6088 unblock_input (); 6055 unblock_input ();
6056
6057 if (f->want_fullscreen == FULLSCREEN_BOTH
6058 || f->want_fullscreen == FULLSCREEN_WIDTH
6059 || f->want_fullscreen == FULLSCREEN_HEIGHT)
6060 do_pending_window_change (0);
6061
6089 } 6062 }
6090 else 6063 else
6091 f->want_fullscreen |= FULLSCREEN_WAIT; 6064 f->want_fullscreen |= FULLSCREEN_WAIT;
@@ -6101,6 +6074,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6101 int width, int height, bool pixelwise) 6074 int width, int height, bool pixelwise)
6102{ 6075{
6103 int pixelwidth, pixelheight; 6076 int pixelwidth, pixelheight;
6077 Lisp_Object fullscreen = get_frame_param (f, Qfullscreen);
6104 RECT rect; 6078 RECT rect;
6105 6079
6106 block_input (); 6080 block_input ();
@@ -6119,7 +6093,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
6119 if (w32_add_wrapped_menu_bar_lines) 6093 if (w32_add_wrapped_menu_bar_lines)
6120 { 6094 {
6121 /* When the menu bar wraps sending a SetWindowPos shrinks the 6095 /* When the menu bar wraps sending a SetWindowPos shrinks the
6122 height of the frame when the wrapped menu bar lines are not 6096 height of the frame then the wrapped menu bar lines are not
6123 accounted for (Bug#15174 and Bug#18720). Here we add these 6097 accounted for (Bug#15174 and Bug#18720). Here we add these
6124 extra lines to the frame height. */ 6098 extra lines to the frame height. */
6125 MENUBARINFO info; 6099 MENUBARINFO info;
@@ -6143,9 +6117,6 @@ x_set_window_size (struct frame *f, bool change_gravity,
6143 f->win_gravity = NorthWestGravity; 6117 f->win_gravity = NorthWestGravity;
6144 x_wm_set_size_hint (f, (long) 0, false); 6118 x_wm_set_size_hint (f, (long) 0, false);
6145 6119
6146 f->want_fullscreen = FULLSCREEN_NONE;
6147 w32fullscreen_hook (f);
6148
6149 rect.left = rect.top = 0; 6120 rect.left = rect.top = 0;
6150 rect.right = pixelwidth; 6121 rect.right = pixelwidth;
6151 rect.bottom = pixelheight; 6122 rect.bottom = pixelheight;
@@ -6153,45 +6124,45 @@ x_set_window_size (struct frame *f, bool change_gravity,
6153 AdjustWindowRect (&rect, f->output_data.w32->dwStyle, 6124 AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
6154 FRAME_EXTERNAL_MENU_BAR (f)); 6125 FRAME_EXTERNAL_MENU_BAR (f));
6155 6126
6156 my_set_window_pos (FRAME_W32_WINDOW (f), 6127 if (!(f->after_make_frame)
6157 NULL, 6128 && !(f->want_fullscreen & FULLSCREEN_WAIT)
6158 0, 0, 6129 && FRAME_VISIBLE_P (f))
6159 rect.right - rect.left, 6130 {
6160 rect.bottom - rect.top, 6131 RECT window_rect;
6161 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 6132
6162 6133 GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
6163 /* If w32_enable_frame_resize_hack is non-nil, immediately apply the
6164 new pixel sizes to the frame and its subwindows.
6165
6166 Jason Rumney earlier refused to call change_frame_size right here
6167 with the following argument:
6168
6169 The following mirrors what is done in xterm.c. It appears to be for
6170 informing lisp of the new size immediately, while the actual resize
6171 will happen asynchronously. But on Windows, the menu bar
6172 automatically wraps when the frame is too narrow to contain it, and
6173 that causes any calculations made here to come out wrong. The end
6174 is some nasty buggy behavior, including the potential loss of the
6175 minibuffer.
6176
6177 Disabling this code is either not sufficient to fix the problems
6178 completely, or it causes fresh problems, but at least it removes
6179 the most problematic symptom of the minibuffer becoming unusable.
6180
6181 However, as the discussion about how to handle frame size
6182 parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems
6183 worse than the disease. In particular, menu bar wrapping looks
6184 like a non-issue - maybe so because Windows eventually gets back to
6185 us with the correct client rectangle anyway. But we have to avoid
6186 calling change_frame_size with a delta of less than one canoncial
6187 character size when frame_resize_pixelwise is nil, as explained in
6188 the comment above. */
6189
6190 if (w32_enable_frame_resize_hack)
6191 6134
6135 if (EQ (fullscreen, Qmaximized)
6136 || EQ (fullscreen, Qfullboth)
6137 || EQ (fullscreen, Qfullwidth))
6138 {
6139 rect.left = window_rect.left;
6140 rect.right = window_rect.right;
6141 pixelwidth = 0;
6142 }
6143 if (EQ (fullscreen, Qmaximized)
6144 || EQ (fullscreen, Qfullboth)
6145 || EQ (fullscreen, Qfullheight))
6146 {
6147 rect.top = window_rect.top;
6148 rect.bottom = window_rect.bottom;
6149 pixelheight = 0;
6150 }
6151 }
6152
6153 if (pixelwidth > 0 || pixelheight > 0)
6192 { 6154 {
6193 change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), 6155 my_set_window_pos (FRAME_W32_WINDOW (f), NULL,
6194 FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), 6156 0, 0,
6157 rect.right - rect.left,
6158 rect.bottom - rect.top,
6159 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
6160
6161 change_frame_size (f,
6162 ((pixelwidth == 0)
6163 ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)),
6164 ((pixelheight == 0)
6165 ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)),
6195 0, 1, 0, 1); 6166 0, 1, 0, 1);
6196 SET_FRAME_GARBAGED (f); 6167 SET_FRAME_GARBAGED (f);
6197 6168
@@ -7102,7 +7073,7 @@ Windows 8. It is set to nil on Windows 9X. */);
7102 w32_unicode_filenames = 0; 7073 w32_unicode_filenames = 0;
7103 7074
7104 7075
7105 /* FIXME: The following two variables will be (hopefully) removed 7076 /* FIXME: The following variable will be (hopefully) removed
7106 before Emacs 25.1 gets released. */ 7077 before Emacs 25.1 gets released. */
7107 7078
7108 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines", 7079 DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines",
@@ -7116,16 +7087,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows
7116API. */); 7087API. */);
7117 w32_add_wrapped_menu_bar_lines = 1; 7088 w32_add_wrapped_menu_bar_lines = 1;
7118 7089
7119 DEFVAR_BOOL ("w32-enable-frame-resize-hack",
7120 w32_enable_frame_resize_hack,
7121 doc: /* Non-nil means enable hack for frame resizing on Windows.
7122A value of nil means to resize frames by sending a corresponding request
7123to the Windows API and changing the pixel sizes of the frame and its
7124windows after the latter calls back. If this is non-nil, Emacs changes
7125the pixel sizes of the frame and its windows at the time it sends the
7126resize request to the API. */);
7127 w32_enable_frame_resize_hack = 1;
7128
7129 /* Tell Emacs about this window system. */ 7090 /* Tell Emacs about this window system. */
7130 Fprovide (Qw32, Qnil); 7091 Fprovide (Qw32, Qnil);
7131} 7092}