]> code.delx.au - gnu-emacs/commitdiff
* src/w32fns.c (w32_fullscreen_rect): New function to compute the
authorErik Charlebois <erikcharlebois@gmail.com>
Sun, 14 Apr 2013 00:58:45 +0000 (20:58 -0400)
committerErik Charlebois <erikcharlebois@gmail.com>
Sun, 14 Apr 2013 00:58:45 +0000 (20:58 -0400)
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
src/w32term.c
src/w32term.h

index 5d3a78f8b9531d6b6c8416956eed2f41767bfba0..d4e4d78e8d1f0919428b1547ce79601690db0103 100644 (file)
@@ -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;
+    }
+}
+
 \f
 
 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");
index d249d6e3252542bafb812c9c4177a181d169c9d3..58b1d3ca308e6d16df6b1c1c834ec0191ef74882 100644 (file)
@@ -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 ();
     }
index 9bb37b31ef578a80bff8bbcc0b705b5b7cc1de97..9c27c09d03d00189d3381661d74ff75978cd58d8 100644 (file)
@@ -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);
 
 \f
 /* 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)
 
 \f
 /* W32-specific scroll bar stuff.  */