From 1f635a07be94be671832e5e3db052139265f6445 Mon Sep 17 00:00:00 2001 From: Erik Charlebois Date: Sat, 13 Apr 2013 20:58:45 -0400 Subject: [PATCH] * 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/w32fns.c | 72 +++++++++++++++++++++++++++++++++ src/w32term.c | 108 ++++++++++++++------------------------------------ src/w32term.h | 11 +++-- 3 files changed, 107 insertions(+), 84 deletions(-) diff --git a/src/w32fns.c b/src/w32fns.c index 5d3a78f8b95..d4e4d78e8d1 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -157,6 +157,8 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); typedef BOOL (WINAPI * GetMonitorInfo_Proc) (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); +typedef HMONITOR (WINAPI * MonitorFromWindow_Proc) + (IN HWND hwnd, IN DWORD dwFlags); TrackMouseEvent_Proc track_mouse_event_fn = NULL; ImmGetCompositionString_Proc get_composition_string_fn = NULL; @@ -165,6 +167,7 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL; ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; MonitorFromPoint_Proc monitor_from_point_fn = NULL; GetMonitorInfo_Proc get_monitor_info_fn = NULL; +MonitorFromWindow_Proc monitor_from_window_fn = NULL; #ifdef NTGUI_UNICODE #define unicode_append_menu AppendMenuW @@ -336,6 +339,66 @@ x_real_positions (FRAME_PTR f, int *xptr, int *yptr) *yptr = rect.top; } +/* Returns the window rectangle appropriate for the given fullscreen mode. + The normal rect parameter was the window's rectangle prior to entering + fullscreen mode. If multiple monitor support is available, the nearest + monitor to the window is chosen. */ + +void +w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect) +{ + struct MONITOR_INFO mi = { sizeof(mi) }; + if (monitor_from_window_fn && get_monitor_info_fn) + { + HMONITOR monitor = + monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST); + get_monitor_info_fn (monitor, &mi); + } + else + { + mi.rcMonitor.left = 0; + mi.rcMonitor.top = 0; + mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN); + mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN); + mi.rcWork.left = 0; + mi.rcWork.top = 0; + mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED); + mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED); + } + + switch (fsmode) + { + case FULLSCREEN_BOTH: + rect->left = mi.rcMonitor.left; + rect->top = mi.rcMonitor.top; + rect->right = mi.rcMonitor.right; + rect->bottom = mi.rcMonitor.bottom; + break; + case FULLSCREEN_MAXIMIZED: + rect->left = mi.rcWork.left; + rect->top = mi.rcWork.top; + rect->right = mi.rcWork.right; + rect->bottom = mi.rcWork.bottom; + break; + case FULLSCREEN_WIDTH: + rect->left = mi.rcWork.left; + rect->top = normal.top; + rect->right = mi.rcWork.right; + rect->bottom = normal.bottom; + break; + case FULLSCREEN_HEIGHT: + rect->left = normal.left; + rect->top = mi.rcWork.top; + rect->right = normal.right; + rect->bottom = mi.rcWork.bottom; + break; + case FULLSCREEN_NONE: + default: + *rect = normal; + break; + } +} + DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, @@ -3691,6 +3754,13 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Don't restrict the sizing of tip frames. */ if (hwnd == tip_window) return 0; + + /* Don't restrict the sizing of fullscreened frames, allowing them to be + flush with the sides of the screen. */ + f = x_window_to_frame (dpyinfo, hwnd); + if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE) + return 0; + { WINDOWPLACEMENT wp; LPWINDOWPOS lppos = (WINDOWPOS *) lParam; @@ -7635,6 +7705,8 @@ globals_of_w32fns (void) GetProcAddress (user32_lib, "MonitorFromPoint"); get_monitor_info_fn = (GetMonitorInfo_Proc) GetProcAddress (user32_lib, "GetMonitorInfoA"); + monitor_from_window_fn = (MonitorFromWindow_Proc) + GetProcAddress (user32_lib, "MonitorFromWindow"); { 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) { if (FRAME_VISIBLE_P (f)) { - int width, height, top_pos, left_pos, pixel_height, pixel_width; - int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f); - RECT workarea_rect; + HWND hwnd = FRAME_W32_WINDOW(f); + DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE); + RECT rect; - block_input (); - /* Record current "normal" dimensions for restoring later. */ - if (!( FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH - || FRAME_PREV_FSMODE (f) == FULLSCREEN_MAXIMIZED)) - { - if (FRAME_PREV_FSMODE (f) != FULLSCREEN_HEIGHT) - { - FRAME_NORMAL_HEIGHT (f) = cur_h; - FRAME_NORMAL_TOP (f) = f->top_pos; - } - if (FRAME_PREV_FSMODE (f) != FULLSCREEN_WIDTH) - { - FRAME_NORMAL_WIDTH (f) = cur_w; - FRAME_NORMAL_LEFT (f) = f->left_pos; - } - } - eassert (FRAME_NORMAL_HEIGHT (f) > 0); - eassert (FRAME_NORMAL_WIDTH (f) > 0); - x_real_positions (f, &f->left_pos, &f->top_pos); - x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos); - - SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0); - pixel_height = workarea_rect.bottom - workarea_rect.top; - pixel_width = workarea_rect.right - workarea_rect.left; - /* Need to send SC_RESTORE to the window, in case we are - resizing from FULLSCREEN_MAXIMIZED. Otherwise, the mouse - resize hints will not be shown by the window manager when the - mouse pointer hovers over the window edges, because the WM - will still think the window is maximized. */ - if (f->want_fullscreen != FULLSCREEN_BOTH) - SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0); + block_input(); + f->want_fullscreen &= ~FULLSCREEN_WAIT; + + if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE) + GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f)); + + if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH) + { + SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW); + SetWindowPos (hwnd, NULL, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + w32_fullscreen_rect (hwnd, f->want_fullscreen, + FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); FRAME_PREV_FSMODE (f) = f->want_fullscreen; - switch (f->want_fullscreen) - { - case FULLSCREEN_BOTH: - PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0); - break; - case FULLSCREEN_MAXIMIZED: - height = - FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) - - XINT (Ftool_bar_lines_needed (selected_frame)) - + (NILP (Vmenu_bar_mode) ? 1 : 0); - width = - FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) - - FRAME_SCROLL_BAR_COLS (f); - left_pos = workarea_rect.left; - top_pos = workarea_rect.top; - break; - case FULLSCREEN_WIDTH: - width = - FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width) - - FRAME_SCROLL_BAR_COLS (f); - height = FRAME_NORMAL_HEIGHT (f); - left_pos = workarea_rect.left; - break; - case FULLSCREEN_HEIGHT: - height = - FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height) - - XINT (Ftool_bar_lines_needed (selected_frame)) - + (NILP (Vmenu_bar_mode) ? 1 : 0); - width = FRAME_NORMAL_WIDTH (f); - top_pos = workarea_rect.top; - break; - case FULLSCREEN_NONE: - height = FRAME_NORMAL_HEIGHT (f); - width = FRAME_NORMAL_WIDTH (f); - left_pos = FRAME_NORMAL_LEFT (f); - top_pos = FRAME_NORMAL_TOP (f); - break; - } + if (f->want_fullscreen == FULLSCREEN_BOTH) + { + SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); + SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + else + { + SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, 0); + } - if (cur_w != width || cur_h != height) - { - x_set_offset (f, left_pos, top_pos, 1); - x_set_window_size (f, 1, width, height); - do_pending_window_change (0); - } f->want_fullscreen = FULLSCREEN_NONE; unblock_input (); } 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 { }; extern void w32_regenerate_palette (struct frame *f); +extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, + RECT *rect); /* For each display (currently only one on w32), we have a structure that @@ -362,7 +364,7 @@ struct w32_output /* Frame geometry and full-screen mode before it was resized by specifying the 'fullscreen' frame parameter. Used to restore the geometry when 'fullscreen' is reset to nil. */ - int normal_width, normal_height, normal_top, normal_left; + WINDOWPLACEMENT normal_placement; int prev_fsmode; }; @@ -396,11 +398,8 @@ extern struct w32_output w32term_display; #define FRAME_SMALLEST_FONT_HEIGHT(F) \ FRAME_W32_DISPLAY_INFO(F)->smallest_font_height -#define FRAME_NORMAL_WIDTH(F) ((F)->output_data.w32->normal_width) -#define FRAME_NORMAL_HEIGHT(F) ((F)->output_data.w32->normal_height) -#define FRAME_NORMAL_TOP(F) ((F)->output_data.w32->normal_top) -#define FRAME_NORMAL_LEFT(F) ((F)->output_data.w32->normal_left) -#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode) +#define FRAME_NORMAL_PLACEMENT(F) ((F)->output_data.w32->normal_placement) +#define FRAME_PREV_FSMODE(F) ((F)->output_data.w32->prev_fsmode) /* W32-specific scroll bar stuff. */ -- 2.39.2