From cdc0d0bdbd039dd8c826568123b7ae53bc848373 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 23 Mar 2013 21:40:43 +0200 Subject: [PATCH] Fix fullscreen resizing of multiple frames on MS-Windows. 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 | 14 ++++++++++++++ src/w32term.c | 47 +++++++++++++++++++++++------------------------ src/w32term.h | 13 +++++++++++++ 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c60ff058e9d..62f210583ee 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,19 @@ 2013-03-23 Eli Zaretskii + * 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 diff --git a/src/w32term.c b/src/w32term.c index 3fe16b956bd..66d11164594 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -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; } diff --git a/src/w32term.h b/src/w32term.h index a31c5de193d..b319f0ca592 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -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) + /* W32-specific scroll bar stuff. */ -- 2.39.2