diff options
Diffstat (limited to 'src/w32term.c')
| -rw-r--r-- | src/w32term.c | 217 |
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 *); |
| 3347 | static void x_check_fullscreen (struct frame *); | ||
| 3348 | |||
| 3349 | static void | 3347 | static void |
| 3350 | w32_define_cursor (Window window, Cursor cursor) | 3348 | w32_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 | |||
| 5968 | static void | ||
| 5969 | x_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. */ | ||
| 6006 | static void | ||
| 6007 | x_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 | |||
| 6031 | static void | 5971 | static void |
| 6032 | w32fullscreen_hook (struct frame *f) | 5972 | w32fullscreen_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 | |||
| 7116 | API. */); | 7087 | API. */); |
| 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. | ||
| 7122 | A value of nil means to resize frames by sending a corresponding request | ||
| 7123 | to the Windows API and changing the pixel sizes of the frame and its | ||
| 7124 | windows after the latter calls back. If this is non-nil, Emacs changes | ||
| 7125 | the pixel sizes of the frame and its windows at the time it sends the | ||
| 7126 | resize 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 | } |