Fix fullscreen resizing of multiple frames on MS-Windows.
authorEli Zaretskii <eliz@gnu.org>
Sat, 23 Mar 2013 19:40:43 +0000 (21:40 +0200)
committerEli Zaretskii <eliz@gnu.org>
Sat, 23 Mar 2013 19:40:43 +0000 (21:40 +0200)
 src/w32term.h (struct w32_output): New members normal_width,
 normal_height, normal_top, normal_left, and prev_fsmode.
 (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP)
 (FRAME_NORMAL_LEFT, FRAME_PREV_FSMODE): New macros to access these
 members of a frame.
 src/w32term.c (w32fullscreen_hook): Use FRAME_NORMAL_WIDTH,
 FRAME_NORMAL_HEIGHT, and FRAME_PREV_FSMODE, instead of static
 variables, to save and restore frame dimensions.  Use
 FRAME_NORMAL_LEFT and FRAME_NORMAL_TOP to restore frame position
 after returning from a 'fullscreen' configuration.  use
 SendMessage instead of PostMessage to send the SC_RESTORE message,
 to avoid races between the main thread and the input thread.

src/ChangeLog
src/w32term.c
src/w32term.h

index c60ff05..62f2105 100644 (file)
@@ -1,5 +1,19 @@
 2013-03-23  Eli Zaretskii  <eliz@gnu.org>
 
+       * w32term.c (w32fullscreen_hook): Use FRAME_NORMAL_WIDTH,
+       FRAME_NORMAL_HEIGHT, and FRAME_PREV_FSMODE, instead of static
+       variables, to save and restore frame dimensions.  Use
+       FRAME_NORMAL_LEFT and FRAME_NORMAL_TOP to restore frame position
+       after returning from a 'fullscreen' configuration.  use
+       SendMessage instead of PostMessage to send the SC_RESTORE message,
+       to avoid races between the main thread and the input thread.
+
+       * w32term.h (struct w32_output): New members normal_width,
+       normal_height, normal_top, normal_left, and prev_fsmode.
+       (FRAME_NORMAL_WIDTH, FRAME_NORMAL_HEIGHT, FRAME_NORMAL_TOP)
+       (FRAME_NORMAL_LEFT, FRAME_PREV_FSMODE): New macros to access these
+       members of a frame.
+
        * w32term.c (w32fullscreen_hook): Record last value of the frame's
        'fullscreen' parameter.  Always record previous width and height
        of the frame, except when switching out of maximized modes, so
index 3fe16b9..66d1116 100644 (file)
@@ -5660,9 +5660,6 @@ x_check_fullscreen (struct frame *f)
 static void
 w32fullscreen_hook (FRAME_PTR f)
 {
-  static int normal_width, normal_height;
-  static Lisp_Object prev_full;
-
   if (FRAME_VISIBLE_P (f))
     {
       int width, height, top_pos, left_pos, pixel_height, pixel_width;
@@ -5670,17 +5667,23 @@ w32fullscreen_hook (FRAME_PTR f)
       RECT workarea_rect;
 
       block_input ();
-      if (!(   EQ (prev_full, Qfullscreen)
-           || EQ (prev_full, Qfullboth)
-           || EQ (prev_full, Qmaximized)))
+      /* Record current "normal" dimensions for restoring later.  */
+      if (!(   FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH
+           || FRAME_PREV_FSMODE (f) == FULLSCREEN_MAXIMIZED))
        {
-         if (!EQ (prev_full, Qfullheight))
-           normal_height = cur_h;
-         if (!EQ (prev_full, Qfullwidth))
-           normal_width  = cur_w;
+         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 (normal_height > 0);
-      eassert (normal_width > 0);
+      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);
 
@@ -5693,16 +5696,15 @@ w32fullscreen_hook (FRAME_PTR f)
         mouse pointer hovers over the window edges, becaise the WM
         will still think the window is maximized.  */
       if (f->want_fullscreen != FULLSCREEN_BOTH)
-       PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0);
+       SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0);
 
+      FRAME_PREV_FSMODE (f) = f->want_fullscreen;
       switch (f->want_fullscreen)
        {
        case FULLSCREEN_BOTH:
-         prev_full = Qfullboth;
          PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
          break;
        case FULLSCREEN_MAXIMIZED:
-         prev_full = Qmaximized;
          height =
            FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
            - XINT (Ftool_bar_lines_needed (selected_frame))
@@ -5714,28 +5716,25 @@ w32fullscreen_hook (FRAME_PTR f)
          top_pos = workarea_rect.top;
          break;
        case FULLSCREEN_WIDTH:
-         prev_full = Qfullwidth;
          width  =
            FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
            - FRAME_SCROLL_BAR_COLS (f);
-         height = normal_height;
+         height = FRAME_NORMAL_HEIGHT (f);
          left_pos = workarea_rect.left;
          break;
        case FULLSCREEN_HEIGHT:
-         prev_full = Qfullheight;
          height =
            FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
            - XINT (Ftool_bar_lines_needed (selected_frame))
            + (NILP (Vmenu_bar_mode) ? 1 : 0);
-         width = normal_width;
+         width = FRAME_NORMAL_WIDTH (f);
          top_pos = workarea_rect.top;
          break;
        case FULLSCREEN_NONE:
-         prev_full = Qnil;
-         height = normal_height;
-         width = normal_width;
-         /* FIXME: Should restore the original position of the frame.  */
-         top_pos = left_pos = 0;
+         height = FRAME_NORMAL_HEIGHT (f);
+         width = FRAME_NORMAL_WIDTH (f);
+         left_pos = FRAME_NORMAL_LEFT (f);
+         top_pos = FRAME_NORMAL_TOP (f);
          break;
        }
 
index a31c5de..b319f0c 100644 (file)
@@ -359,6 +359,12 @@ struct w32_output
   /* The background for which the above relief GCs were set up.
      They are changed only when a different background is involved.  */
   unsigned long relief_background;
+
+  /* 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;
+  int prev_fsmode;
 };
 
 extern struct w32_output w32term_display;
@@ -390,6 +396,13 @@ 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)
+
 \f
 /* W32-specific scroll bar stuff.  */