Package: emacs;
Reported by: Andrii Kolomoiets <andreyk.mad <at> gmail.com>
Date: Mon, 23 Mar 2020 18:14:01 UTC
Severity: normal
Found in version 28.0.50
Done: Alan Third <alan <at> idiocy.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Alan Third <alan <at> idiocy.org> To: Andrii Kolomoiets <andreyk.mad <at> gmail.com> Cc: 40200 <at> debbugs.gnu.org, aaronjensen <at> gmail.com, 28872 <at> debbugs.gnu.org Subject: bug#40200: [PATCH v2] Fix NS frame resizing issues (bug#40200, bug#28872) Date: Thu, 26 Mar 2020 22:21:29 +0100 (CET)
* src/nsmenu.m (update_frame_tool_bar): Remove reference to updateFrameSize. * src/nsterm.h: ([EmacsView updateFrameSize]): ([EmacsView setRows:andColumns:]): Remove unused method definitions. * src/nsterm.m (ns_set_window_size): (ns_set_undecorated): ([EmacsView windowDidResize:]): ([EmacsView windowDidExitFullScreen]): (ns_judge_scroll_bars): Remove references to updateFrameSize. ([EmacsView dealloc]): Unset resize notification and release buffer. ([EmacsView updateFrameSize:]): Remove function. ([EmacsView windowWillResize:toSize:]): Move some code to viewDidResize. ([EmacsView viewDidResize]): New function. ([EmacsView initFrameFromEmacs:]): Set up resize notification and move buffer creation until after the prerequisite objects are created. ([EmacsView toggleFullScreen:]): Set frame to the size of the contentview, not the whole window, and remove reference to updateFrameSize. ([EmacsView setRows:andColumns:]): Remove unused method. --- Hopefully this works better. src/nsmenu.m | 2 - src/nsterm.h | 3 - src/nsterm.m | 189 ++++++++++++++++++--------------------------------- 3 files changed, 68 insertions(+), 126 deletions(-) diff --git a/src/nsmenu.m b/src/nsmenu.m index 67f9a45a40..b7e4cbd565 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m @@ -1141,8 +1141,6 @@ - (Lisp_Object)runMenuAt: (NSPoint)p forFrame: (struct frame *)f } #endif - if (oldh != FRAME_TOOLBAR_HEIGHT (f)) - [view updateFrameSize:YES]; if (view->wait_for_tool_bar && FRAME_TOOLBAR_HEIGHT (f) > 0) { view->wait_for_tool_bar = NO; diff --git a/src/nsterm.h b/src/nsterm.h index 8396a542f7..3c2e4c2b07 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -439,7 +439,6 @@ #define NS_DRAW_TO_BUFFER 1 #endif @public struct frame *emacsframe; - int rows, cols; int scrollbarsNeedingUpdate; EmacsToolbar *toolbar; NSRect ns_userRect; @@ -458,11 +457,9 @@ #define NS_DRAW_TO_BUFFER 1 /* Emacs-side interface */ - (instancetype) initFrameFromEmacs: (struct frame *) f; - (void) createToolbar: (struct frame *)f; -- (void) setRows: (int) r andColumns: (int) c; - (void) setWindowClosing: (BOOL)closing; - (EmacsToolbar *) toolbar; - (void) deleteWorkingText; -- (void) updateFrameSize: (BOOL) delay; - (void) handleFS; - (void) setFSValue: (int)value; - (void) toggleFullScreen: (id) sender; diff --git a/src/nsterm.m b/src/nsterm.m index 04fc051223..95ab4390a0 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1864,7 +1864,6 @@ Hide the window (X11 semantics) [window setFrame: wr display: YES]; - [view updateFrameSize: NO]; unblock_input (); } @@ -1913,7 +1912,6 @@ Hide the window (X11 semantics) so some key presses (TAB) are swallowed by the system. */ [window makeFirstResponder: view]; - [view updateFrameSize: NO]; unblock_input (); } } @@ -5024,9 +5022,6 @@ in certain situations (rapid incoming events). if ([view judge]) removed = YES; } - - if (removed) - [eview updateFrameSize: NO]; } /* ========================================================================== @@ -6198,6 +6193,15 @@ - (void) setWindowClosing: (BOOL)closing - (void)dealloc { NSTRACE ("[EmacsView dealloc]"); + + /* Clear the view resize notification. */ + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:NSViewFrameDidChangeNotification + object:nil]; + + CGContextRelease (drawingBuffer); + [toolbar release]; if (fs_state == FULLSCREEN_BOTH) [nonfs_window release]; @@ -7039,108 +7043,12 @@ - (BOOL)windowShouldClose: (id)sender return NO; } -- (void) updateFrameSize: (BOOL) delay -{ - NSWindow *window = [self window]; - NSRect wr = [window frame]; - int extra = 0; - int oldc = cols, oldr = rows; - int oldw = FRAME_PIXEL_WIDTH (emacsframe); - int oldh = FRAME_PIXEL_HEIGHT (emacsframe); - int neww, newh; - - NSTRACE ("[EmacsView updateFrameSize:]"); - NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); - NSTRACE_RECT ("Original frame", wr); - NSTRACE_MSG ("Original columns: %d", cols); - NSTRACE_MSG ("Original rows: %d", rows); - - if (! [self isFullscreen]) - { - int toolbar_height; -#ifdef NS_IMPL_GNUSTEP - // GNUstep does not always update the tool bar height. Force it. - if (toolbar && [toolbar isVisible]) - update_frame_tool_bar (emacsframe); -#endif - - toolbar_height = FRAME_TOOLBAR_HEIGHT (emacsframe); - if (toolbar_height < 0) - toolbar_height = 35; - - extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) - + toolbar_height; - } - - if (wait_for_tool_bar) - { - /* The toolbar height is always 0 in fullscreen and undecorated - frames, so don't wait for it to become available. */ - if (FRAME_TOOLBAR_HEIGHT (emacsframe) == 0 - && FRAME_UNDECORATED (emacsframe) == false - && ! [self isFullscreen]) - { - NSTRACE_MSG ("Waiting for toolbar"); - return; - } - wait_for_tool_bar = NO; - } - - neww = (int)wr.size.width - emacsframe->border_width; - newh = (int)wr.size.height - extra; - - NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); - NSTRACE_MSG ("FRAME_TOOLBAR_HEIGHT: %d", FRAME_TOOLBAR_HEIGHT (emacsframe)); - NSTRACE_MSG ("FRAME_NS_TITLEBAR_HEIGHT: %d", FRAME_NS_TITLEBAR_HEIGHT (emacsframe)); - - cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww); - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh); - - if (cols < MINWIDTH) - cols = MINWIDTH; - - if (rows < MINHEIGHT) - rows = MINHEIGHT; - - NSTRACE_MSG ("New columns: %d", cols); - NSTRACE_MSG ("New rows: %d", rows); - - if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) - { - NSView *view = FRAME_NS_VIEW (emacsframe); - - change_frame_size (emacsframe, - FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww), - FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), - 0, delay, 0, 1); - SET_FRAME_GARBAGED (emacsframe); - cancel_mouse_face (emacsframe); - - /* The next two lines set the frame to the same size as we've - already set above. We need to do this when we switch back - from non-native fullscreen, in other circumstances it appears - to be a noop. (bug#28872) */ - wr = NSMakeRect (0, 0, neww, newh); - [view setFrame: wr]; -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif - - // To do: consider using [NSNotificationCenter postNotificationName:]. - [self windowDidMove: // Update top/left. - [NSNotification notificationWithName:NSWindowDidMoveNotification - object:[view window]]]; - } - else - { - NSTRACE_MSG ("No change"); - } -} - (NSSize)windowWillResize: (NSWindow *)sender toSize: (NSSize)frameSize /* Normalize frame to gridded text size. */ { int extra = 0; + int cols, rows; NSTRACE ("[EmacsView windowWillResize:toSize: " NSTRACE_FMT_SIZE "]", NSTRACE_ARG_SIZE (frameSize)); @@ -7277,11 +7185,6 @@ - (void)windowDidResize: (NSNotification *)notification sz = [self windowWillResize: theWindow toSize: sz]; #endif /* NS_IMPL_GNUSTEP */ - if (cols > 0 && rows > 0) - { - [self updateFrameSize: YES]; - } - ns_send_appdefined (-1); } @@ -7302,6 +7205,51 @@ - (void)viewDidEndLiveResize #endif /* NS_IMPL_COCOA */ +- (void)viewDidResize:(NSNotification *)notification +{ + NSRect frame = [self frame]; + int oldw, oldh, neww, newh; + + if (! FRAME_LIVE_P (emacsframe)) + return; + +#ifdef NS_DRAW_TO_BUFFER + CGFloat scale = [[self window] backingScaleFactor]; + oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; + oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; +#else + oldw = FRAME_PIXEL_WIDTH (emacsframe); + oldh = FRAME_PIXEL_HEIGHT (emacsframe); +#endif + neww = (int)NSWidth (frame); + newh = (int)NSHeight (frame); + + NSTRACE ("[EmacsView viewDidResize]"); + + /* Don't want to do anything when the view size hasn't changed. */ + if ((oldh == newh && oldw == neww)) + { + NSTRACE_MSG ("No change"); + return; + } + + NSTRACE_SIZE ("Original size", NSMakeSize (oldw, oldh)); + NSTRACE_SIZE ("New size", NSMakeSize (neww, newh)); + + change_frame_size (emacsframe, + FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww), + FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), + 0, YES, 0, 1); + +#ifdef NS_DRAW_TO_BUFFER + [self createDrawingBuffer]; +#endif + ns_clear_frame (emacsframe); + SET_FRAME_GARBAGED (emacsframe); + cancel_mouse_face (emacsframe); +} + + - (void)windowDidBecomeKey: (NSNotification *)notification /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { @@ -7463,10 +7411,6 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f maximizing_resize = NO; #endif -#ifdef NS_DRAW_TO_BUFFER - [self createDrawingBuffer]; -#endif - win = [[EmacsWindow alloc] initWithContentRect: r styleMask: (FRAME_UNDECORATED (f) @@ -7572,6 +7516,17 @@ - (instancetype) initFrameFromEmacs: (struct frame *)f [NSApp registerServicesMenuSendTypes: ns_send_types returnTypes: [NSArray array]]; +#ifdef NS_DRAW_TO_BUFFER + [self createDrawingBuffer]; +#endif + + /* Set up view resize notifications. */ + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector (viewDidResize:) + name:NSViewFrameDidChangeNotification object:nil]; + /* macOS Sierra automatically enables tabbed windows. We can't allow this to be enabled until it's available on a Free system. Currently it only happens by accident and is buggy anyway. */ @@ -7902,7 +7857,6 @@ - (void)windowDidExitFullScreen /* provided for direct calls */ { [toolbar setVisible:YES]; update_frame_tool_bar (emacsframe); - [self updateFrameSize:YES]; [[self window] display]; } else @@ -8115,11 +8069,11 @@ - (void)toggleFullScreen: (id)sender // send notifications. [self windowWillExitFullScreen]; - [fw setFrame: [w frame] display:YES animate:ns_use_fullscreen_animation]; + [fw setFrame:[[w contentView] frame] + display:YES animate:ns_use_fullscreen_animation]; [fw close]; [w makeKeyAndOrderFront:NSApp]; [self windowDidExitFullScreen]; - [self updateFrameSize:YES]; } } @@ -8628,13 +8582,6 @@ - (instancetype)setMiniwindowImage: (BOOL) setMini } -- (void) setRows: (int) r andColumns: (int) c -{ - NSTRACE ("[EmacsView setRows:%d andColumns:%d]", r, c); - rows = r; - cols = c; -} - - (int) fullscreenState { return fs_state; -- 2.24.0 -- Alan Third
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.