diff options
| author | Erik Charlebois | 2013-04-20 10:32:31 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-04-20 10:32:31 +0300 |
| commit | 806bda47ddb469f6206ecc533458eadae6a5b575 (patch) | |
| tree | 8f5723c3984be59136b488290889ea5cab6573df /src | |
| parent | 38ef2c8490eaa74e22504386beebc6d88d287094 (diff) | |
| parent | 1f635a07be94be671832e5e3db052139265f6445 (diff) | |
| download | emacs-806bda47ddb469f6206ecc533458eadae6a5b575.tar.gz emacs-806bda47ddb469f6206ecc533458eadae6a5b575.zip | |
Better full-screen frame support on MS-Windows.
src/w32fns.c (w32_fullscreen_rect): New function to compute the
window rectangle for the given fullscreen mode.
(w32_wnd_proc): When in a fullscreen mode, WM_WINDOWPOSCHANGING no
longer tunes the window size. This keeps the window's edges flush
with the screen and allows the taskbar to hide itself in fullboth.
src/w32term.c (w32fullscreen_hook): 'fullboth' now shows without
window decorations and uses the entire screen.
src/w32term.h (w32_fullscreen_rect) Add prototype.
(struct w32_output): Replace normal_width, normal_height,
normal_top, and normal_left members with a single normal_placement
struct.
(FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP):
Remove macros.
(FRAME_NORMAL_PLACEMENT): New macro.
Fixes: debbugs:14180
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 19 | ||||
| -rw-r--r-- | src/w32fns.c | 72 | ||||
| -rw-r--r-- | src/w32term.c | 108 | ||||
| -rw-r--r-- | src/w32term.h | 11 |
4 files changed, 126 insertions, 84 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 04a6c353619..5164dc8ff8d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,22 @@ | |||
| 1 | 2013-04-20 Erik Charlebois <erikcharlebois@gmail.com> | ||
| 2 | |||
| 3 | * w32fns.c (w32_fullscreen_rect): New function to compute the | ||
| 4 | window rectangle for the given fullscreen mode. | ||
| 5 | (w32_wnd_proc): When in a fullscreen mode, WM_WINDOWPOSCHANGING no | ||
| 6 | longer tunes the window size. This keeps the window's edges flush | ||
| 7 | with the screen and allows the taskbar to hide itself in fullboth. | ||
| 8 | |||
| 9 | * w32term.c (w32fullscreen_hook): 'fullboth' now shows without | ||
| 10 | window decorations and uses the entire screen. | ||
| 11 | |||
| 12 | * w32term.h (w32_fullscreen_rect) Add prototype. | ||
| 13 | (struct w32_output): Replace normal_width, normal_height, | ||
| 14 | normal_top, and normal_left members with a single normal_placement | ||
| 15 | struct. | ||
| 16 | (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP): | ||
| 17 | Remove macros. | ||
| 18 | (FRAME_NORMAL_PLACEMENT): New macro. | ||
| 19 | |||
| 1 | 2013-04-16 Juanma Barranquero <lekktu@gmail.com> | 20 | 2013-04-16 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 21 | ||
| 3 | * minibuf.c (Ftest_completion): Silence compiler warning. | 22 | * minibuf.c (Ftest_completion): Silence compiler warning. |
diff --git a/src/w32fns.c b/src/w32fns.c index de52ff144e3..0785e685e6a 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -157,6 +157,8 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, | |||
| 157 | typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); | 157 | typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); |
| 158 | typedef BOOL (WINAPI * GetMonitorInfo_Proc) | 158 | typedef BOOL (WINAPI * GetMonitorInfo_Proc) |
| 159 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); | 159 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); |
| 160 | typedef HMONITOR (WINAPI * MonitorFromWindow_Proc) | ||
| 161 | (IN HWND hwnd, IN DWORD dwFlags); | ||
| 160 | 162 | ||
| 161 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; | 163 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; |
| 162 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; | 164 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; |
| @@ -165,6 +167,7 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL; | |||
| 165 | ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; | 167 | ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; |
| 166 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; | 168 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; |
| 167 | GetMonitorInfo_Proc get_monitor_info_fn = NULL; | 169 | GetMonitorInfo_Proc get_monitor_info_fn = NULL; |
| 170 | MonitorFromWindow_Proc monitor_from_window_fn = NULL; | ||
| 168 | 171 | ||
| 169 | #ifdef NTGUI_UNICODE | 172 | #ifdef NTGUI_UNICODE |
| 170 | #define unicode_append_menu AppendMenuW | 173 | #define unicode_append_menu AppendMenuW |
| @@ -336,6 +339,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr) | |||
| 336 | *yptr = rect.top; | 339 | *yptr = rect.top; |
| 337 | } | 340 | } |
| 338 | 341 | ||
| 342 | /* Returns the window rectangle appropriate for the given fullscreen mode. | ||
| 343 | The normal rect parameter was the window's rectangle prior to entering | ||
| 344 | fullscreen mode. If multiple monitor support is available, the nearest | ||
| 345 | monitor to the window is chosen. */ | ||
| 346 | |||
| 347 | void | ||
| 348 | w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect) | ||
| 349 | { | ||
| 350 | struct MONITOR_INFO mi = { sizeof(mi) }; | ||
| 351 | if (monitor_from_window_fn && get_monitor_info_fn) | ||
| 352 | { | ||
| 353 | HMONITOR monitor = | ||
| 354 | monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST); | ||
| 355 | get_monitor_info_fn (monitor, &mi); | ||
| 356 | } | ||
| 357 | else | ||
| 358 | { | ||
| 359 | mi.rcMonitor.left = 0; | ||
| 360 | mi.rcMonitor.top = 0; | ||
| 361 | mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN); | ||
| 362 | mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN); | ||
| 363 | mi.rcWork.left = 0; | ||
| 364 | mi.rcWork.top = 0; | ||
| 365 | mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED); | ||
| 366 | mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED); | ||
| 367 | } | ||
| 368 | |||
| 369 | switch (fsmode) | ||
| 370 | { | ||
| 371 | case FULLSCREEN_BOTH: | ||
| 372 | rect->left = mi.rcMonitor.left; | ||
| 373 | rect->top = mi.rcMonitor.top; | ||
| 374 | rect->right = mi.rcMonitor.right; | ||
| 375 | rect->bottom = mi.rcMonitor.bottom; | ||
| 376 | break; | ||
| 377 | case FULLSCREEN_MAXIMIZED: | ||
| 378 | rect->left = mi.rcWork.left; | ||
| 379 | rect->top = mi.rcWork.top; | ||
| 380 | rect->right = mi.rcWork.right; | ||
| 381 | rect->bottom = mi.rcWork.bottom; | ||
| 382 | break; | ||
| 383 | case FULLSCREEN_WIDTH: | ||
| 384 | rect->left = mi.rcWork.left; | ||
| 385 | rect->top = normal.top; | ||
| 386 | rect->right = mi.rcWork.right; | ||
| 387 | rect->bottom = normal.bottom; | ||
| 388 | break; | ||
| 389 | case FULLSCREEN_HEIGHT: | ||
| 390 | rect->left = normal.left; | ||
| 391 | rect->top = mi.rcWork.top; | ||
| 392 | rect->right = normal.right; | ||
| 393 | rect->bottom = mi.rcWork.bottom; | ||
| 394 | break; | ||
| 395 | case FULLSCREEN_NONE: | ||
| 396 | default: | ||
| 397 | *rect = normal; | ||
| 398 | break; | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 339 | 402 | ||
| 340 | 403 | ||
| 341 | DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, | 404 | DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, |
| @@ -3693,6 +3756,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 3693 | /* Don't restrict the sizing of tip frames. */ | 3756 | /* Don't restrict the sizing of tip frames. */ |
| 3694 | if (hwnd == tip_window) | 3757 | if (hwnd == tip_window) |
| 3695 | return 0; | 3758 | return 0; |
| 3759 | |||
| 3760 | /* Don't restrict the sizing of fullscreened frames, allowing them to be | ||
| 3761 | flush with the sides of the screen. */ | ||
| 3762 | f = x_window_to_frame (dpyinfo, hwnd); | ||
| 3763 | if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE) | ||
| 3764 | return 0; | ||
| 3765 | |||
| 3696 | { | 3766 | { |
| 3697 | WINDOWPLACEMENT wp; | 3767 | WINDOWPLACEMENT wp; |
| 3698 | LPWINDOWPOS lppos = (WINDOWPOS *) lParam; | 3768 | LPWINDOWPOS lppos = (WINDOWPOS *) lParam; |
| @@ -7637,6 +7707,8 @@ globals_of_w32fns (void) | |||
| 7637 | GetProcAddress (user32_lib, "MonitorFromPoint"); | 7707 | GetProcAddress (user32_lib, "MonitorFromPoint"); |
| 7638 | get_monitor_info_fn = (GetMonitorInfo_Proc) | 7708 | get_monitor_info_fn = (GetMonitorInfo_Proc) |
| 7639 | GetProcAddress (user32_lib, "GetMonitorInfoA"); | 7709 | GetProcAddress (user32_lib, "GetMonitorInfoA"); |
| 7710 | monitor_from_window_fn = (MonitorFromWindow_Proc) | ||
| 7711 | GetProcAddress (user32_lib, "MonitorFromWindow"); | ||
| 7640 | 7712 | ||
| 7641 | { | 7713 | { |
| 7642 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); | 7714 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); |
diff --git a/src/w32term.c b/src/w32term.c index d249d6e3252..58b1d3ca308 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -5663,88 +5663,40 @@ w32fullscreen_hook (FRAME_PTR f) | |||
| 5663 | { | 5663 | { |
| 5664 | if (FRAME_VISIBLE_P (f)) | 5664 | if (FRAME_VISIBLE_P (f)) |
| 5665 | { | 5665 | { |
| 5666 | int width, height, top_pos, left_pos, pixel_height, pixel_width; | 5666 | HWND hwnd = FRAME_W32_WINDOW(f); |
| 5667 | int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f); | 5667 | DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); |
| 5668 | RECT workarea_rect; | 5668 | RECT rect; |
| 5669 | 5669 | ||
| 5670 | block_input (); | 5670 | block_input(); |
| 5671 | /* Record current "normal" dimensions for restoring later. */ | 5671 | f->want_fullscreen &= ~FULLSCREEN_WAIT; |
| 5672 | if (!( FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH | 5672 | |
| 5673 | || FRAME_PREV_FSMODE (f) == FULLSCREEN_MAXIMIZED)) | 5673 | if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE) |
| 5674 | { | 5674 | GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f)); |
| 5675 | if (FRAME_PREV_FSMODE (f) != FULLSCREEN_HEIGHT) | 5675 | |
| 5676 | { | 5676 | if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH) |
| 5677 | FRAME_NORMAL_HEIGHT (f) = cur_h; | 5677 | { |
| 5678 | FRAME_NORMAL_TOP (f) = f->top_pos; | 5678 | SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW); |
| 5679 | } | 5679 | SetWindowPos (hwnd, NULL, 0, 0, 0, 0, |
| 5680 | if (FRAME_PREV_FSMODE (f) != FULLSCREEN_WIDTH) | 5680 | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | |
| 5681 | { | 5681 | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); |
| 5682 | FRAME_NORMAL_WIDTH (f) = cur_w; | 5682 | } |
| 5683 | FRAME_NORMAL_LEFT (f) = f->left_pos; | ||
| 5684 | } | ||
| 5685 | } | ||
| 5686 | eassert (FRAME_NORMAL_HEIGHT (f) > 0); | ||
| 5687 | eassert (FRAME_NORMAL_WIDTH (f) > 0); | ||
| 5688 | x_real_positions (f, &f->left_pos, &f->top_pos); | ||
| 5689 | x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos); | ||
| 5690 | |||
| 5691 | SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); | ||
| 5692 | pixel_height = workarea_rect.bottom - workarea_rect.top; | ||
| 5693 | pixel_width = workarea_rect.right - workarea_rect.left; | ||
| 5694 | /* Need to send SC_RESTORE to the window, in case we are | ||
| 5695 | resizing from FULLSCREEN_MAXIMIZED. Otherwise, the mouse | ||
| 5696 | resize hints will not be shown by the window manager when the | ||
| 5697 | mouse pointer hovers over the window edges, because the WM | ||
| 5698 | will still think the window is maximized. */ | ||
| 5699 | if (f->want_fullscreen != FULLSCREEN_BOTH) | ||
| 5700 | SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0); | ||
| 5701 | 5683 | ||
| 5684 | w32_fullscreen_rect (hwnd, f->want_fullscreen, | ||
| 5685 | FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); | ||
| 5702 | FRAME_PREV_FSMODE (f) = f->want_fullscreen; | 5686 | FRAME_PREV_FSMODE (f) = f->want_fullscreen; |
| 5703 | switch (f->want_fullscreen) | 5687 | if (f->want_fullscreen == FULLSCREEN_BOTH) |
| 5704 | { | 5688 | { |
| 5705 | case FULLSCREEN_BOTH: | 5689 | SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); |
| 5706 | PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0); | 5690 | SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, |
| 5707 | break; | 5691 | rect.right - rect.left, rect.bottom - rect.top, |
| 5708 | case FULLSCREEN_MAXIMIZED: | 5692 | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); |
| 5709 | height = | 5693 | } |
| 5710 | FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) | 5694 | else |
| 5711 | - XINT (Ftool_bar_lines_needed (selected_frame)) | 5695 | { |
| 5712 | + (NILP (Vmenu_bar_mode) ? 1 : 0); | 5696 | SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, |
| 5713 | width = | 5697 | rect.right - rect.left, rect.bottom - rect.top, 0); |
| 5714 | FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) | 5698 | } |
| 5715 | - FRAME_SCROLL_BAR_COLS (f); | ||
| 5716 | left_pos = workarea_rect.left; | ||
| 5717 | top_pos = workarea_rect.top; | ||
| 5718 | break; | ||
| 5719 | case FULLSCREEN_WIDTH: | ||
| 5720 | width = | ||
| 5721 | FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) | ||
| 5722 | - FRAME_SCROLL_BAR_COLS (f); | ||
| 5723 | height = FRAME_NORMAL_HEIGHT (f); | ||
| 5724 | left_pos = workarea_rect.left; | ||
| 5725 | break; | ||
| 5726 | case FULLSCREEN_HEIGHT: | ||
| 5727 | height = | ||
| 5728 | FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) | ||
| 5729 | - XINT (Ftool_bar_lines_needed (selected_frame)) | ||
| 5730 | + (NILP (Vmenu_bar_mode) ? 1 : 0); | ||
| 5731 | width = FRAME_NORMAL_WIDTH (f); | ||
| 5732 | top_pos = workarea_rect.top; | ||
| 5733 | break; | ||
| 5734 | case FULLSCREEN_NONE: | ||
| 5735 | height = FRAME_NORMAL_HEIGHT (f); | ||
| 5736 | width = FRAME_NORMAL_WIDTH (f); | ||
| 5737 | left_pos = FRAME_NORMAL_LEFT (f); | ||
| 5738 | top_pos = FRAME_NORMAL_TOP (f); | ||
| 5739 | break; | ||
| 5740 | } | ||
| 5741 | 5699 | ||
| 5742 | if (cur_w != width || cur_h != height) | ||
| 5743 | { | ||
| 5744 | x_set_offset (f, left_pos, top_pos, 1); | ||
| 5745 | x_set_window_size (f, 1, width, height); | ||
| 5746 | do_pending_window_change (0); | ||
| 5747 | } | ||
| 5748 | f->want_fullscreen = FULLSCREEN_NONE; | 5700 | f->want_fullscreen = FULLSCREEN_NONE; |
| 5749 | unblock_input (); | 5701 | unblock_input (); |
| 5750 | } | 5702 | } |
diff --git a/src/w32term.h b/src/w32term.h index 9bb37b31ef5..9c27c09d03d 100644 --- a/src/w32term.h +++ b/src/w32term.h | |||
| @@ -71,6 +71,8 @@ struct w32_palette_entry { | |||
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | extern void w32_regenerate_palette (struct frame *f); | 73 | extern void w32_regenerate_palette (struct frame *f); |
| 74 | extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, | ||
| 75 | RECT *rect); | ||
| 74 | 76 | ||
| 75 | 77 | ||
| 76 | /* For each display (currently only one on w32), we have a structure that | 78 | /* For each display (currently only one on w32), we have a structure that |
| @@ -362,7 +364,7 @@ struct w32_output | |||
| 362 | /* Frame geometry and full-screen mode before it was resized by | 364 | /* Frame geometry and full-screen mode before it was resized by |
| 363 | specifying the 'fullscreen' frame parameter. Used to restore the | 365 | specifying the 'fullscreen' frame parameter. Used to restore the |
| 364 | geometry when 'fullscreen' is reset to nil. */ | 366 | geometry when 'fullscreen' is reset to nil. */ |
| 365 | int normal_width, normal_height, normal_top, normal_left; | 367 | WINDOWPLACEMENT normal_placement; |
| 366 | int prev_fsmode; | 368 | int prev_fsmode; |
| 367 | }; | 369 | }; |
| 368 | 370 | ||
| @@ -396,11 +398,8 @@ extern struct w32_output w32term_display; | |||
| 396 | #define FRAME_SMALLEST_FONT_HEIGHT(F) \ | 398 | #define FRAME_SMALLEST_FONT_HEIGHT(F) \ |
| 397 | FRAME_W32_DISPLAY_INFO(F)->smallest_font_height | 399 | FRAME_W32_DISPLAY_INFO(F)->smallest_font_height |
| 398 | 400 | ||
| 399 | #define FRAME_NORMAL_WIDTH(F) ((F)->output_data.w32->normal_width) | 401 | #define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement) |
| 400 | #define FRAME_NORMAL_HEIGHT(F) ((F)->output_data.w32->normal_height) | 402 | #define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode) |
| 401 | #define FRAME_NORMAL_TOP(F) ((F)->output_data.w32->normal_top) | ||
| 402 | #define FRAME_NORMAL_LEFT(F) ((F)->output_data.w32->normal_left) | ||
| 403 | #define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode) | ||
| 404 | 403 | ||
| 405 | 404 | ||
| 406 | /* W32-specific scroll bar stuff. */ | 405 | /* W32-specific scroll bar stuff. */ |