emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/ns/refactor d9fd86c2 02/12: Tidy up NS port OS window handling


From: Alan Third
Subject: scratch/ns/refactor d9fd86c2 02/12: Tidy up NS port OS window handling
Date: Sat, 24 Jul 2021 11:40:02 -0400 (EDT)

branch: scratch/ns/refactor
commit d9fd86c24726599c4c4564ee6bcb8454c0d5065b
Author: Alan Third <alan@idiocy.org>
Commit: Alan Third <alan@idiocy.org>

    Tidy up NS port OS window handling
    
    * src/nsterm.h (EmacsWindow): Move above EmacsView definition and add
    new method definitions.
    (EmacsView): Remove redundant bwidth variable, and change NSWindow to
    EmacsWindow.
    (EmacsFSWindow): Delete definition.
    * src/nsterm.m (ns_set_undecorated): Rewrite to work in GNUstep using
    the new OS window creating methods.
    ([EmacsView initFrameFromEmacs:]): Move all NSWindow related code to
    new init method in EmacsWindow, and use said method.
    ([EmacsView toggleFullScreen:]): Use EmacsWindow instead of NSWindow.
    ([EmacsWindow initWithEmacsFrame:]):
    ([EmacsWindow initWithEmacsFrame:fullscreen:screen:]):
    ([EmacsWindow borderWidth]): New methods.
    (EmacsFSWindow): Remove implementation.
---
 src/nsfns.m  |   4 -
 src/nsterm.h |  42 ++++----
 src/nsterm.m | 319 +++++++++++++++++++++++++++++------------------------------
 3 files changed, 175 insertions(+), 190 deletions(-)

diff --git a/src/nsfns.m b/src/nsfns.m
index 454a6fd..c403677 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -947,11 +947,7 @@ frame_parm_handler ns_frame_parm_handlers[] =
   0, /* x_set_sticky */
   0, /* x_set_tool_bar_position */
   0, /* x_set_inhibit_double_buffering */
-#ifdef NS_IMPL_COCOA
   ns_set_undecorated,
-#else
-  0, /* ns_set_undecorated */
-#endif
   ns_set_parent_frame,
   0, /* x_set_skip_taskbar */
   ns_set_no_focus_on_map,
diff --git a/src/nsterm.h b/src/nsterm.h
index 40fd543..b99bea75 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -406,6 +406,24 @@ typedef id instancetype;
 @end
 #endif
 
+/* EmacsWindow  */
+@interface EmacsWindow : NSWindow
+{
+  NSPoint grabOffset;
+}
+
+#ifdef NS_IMPL_GNUSTEP
+- (NSInteger) orderedIndex;
+#endif
+
+- (instancetype)initWithEmacsFrame:(struct frame *)f;
+- (instancetype)initWithEmacsFrame:(struct frame *)f 
fullscreen:(BOOL)fullscreen screen:(NSScreen *)screen;
+- (NSInteger)borderWidth;
+- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above;
+- (void)setAppearance;
+@end
+
+
 /* ==========================================================================
 
    The main Emacs view
@@ -429,9 +447,8 @@ typedef id instancetype;
    NSString *workingText;
    BOOL processingCompose;
    int fs_state, fs_before_fs, next_maximized;
-   int bwidth;
    int maximized_width, maximized_height;
-   NSWindow *nonfs_window;
+   EmacsWindow *nonfs_window;
    BOOL fs_is_native;
 @public
    struct frame *emacsframe;
@@ -485,27 +502,6 @@ typedef id instancetype;
 @end
 
 
-/* Small utility used for processing resize events under Cocoa.  */
-@interface EmacsWindow : NSWindow
-{
-  NSPoint grabOffset;
-}
-
-#ifdef NS_IMPL_GNUSTEP
-- (NSInteger) orderedIndex;
-#endif
-
-- (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above;
-- (void)setAppearance;
-@end
-
-
-/* Fullscreen version of the above.  */
-@interface EmacsFSWindow : EmacsWindow
-{
-}
-@end
-
 /* ==========================================================================
 
    The main menu implementation
diff --git a/src/nsterm.m b/src/nsterm.m
index 0a7cd8c..1600460 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1743,7 +1743,6 @@ ns_set_window_size (struct frame *f,
   unblock_input ();
 }
 
-#ifdef NS_IMPL_COCOA
 void
 ns_set_undecorated (struct frame *f, Lisp_Object new_value, Lisp_Object 
old_value)
 /* --------------------------------------------------------------------------
@@ -1753,45 +1752,37 @@ ns_set_undecorated (struct frame *f, Lisp_Object 
new_value, Lisp_Object old_valu
      dragged, resized, iconified, maximized or deleted with the mouse.  If
      nil, draw the frame with all the elements listed above unless these
      have been suspended via window manager settings.
-
-     GNUStep cannot change an existing window's style.
    -------------------------------------------------------------------------- 
*/
 {
-  EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
-  NSWindow *window = [view window];
-
   NSTRACE ("ns_set_undecorated");
 
   if (!EQ (new_value, old_value))
     {
+      EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
+      NSWindow *oldWindow = [view window];
+      NSWindow *newWindow;
+
       block_input ();
 
-      if (NILP (new_value))
-        {
-          FRAME_UNDECORATED (f) = false;
-          [window setStyleMask: ((window.styleMask | FRAME_DECORATED_FLAGS)
-                                  ^ FRAME_UNDECORATED_FLAGS)];
+      FRAME_UNDECORATED (f) = !NILP (new_value);
 
-          [view createToolbar: f];
-        }
-      else
-        {
-          [window setToolbar: nil];
-          /* Do I need to release the toolbar here?  */
+      newWindow = [[EmacsWindow alloc] initWithEmacsFrame:f];
 
-          FRAME_UNDECORATED (f) = true;
-          [window setStyleMask: ((window.styleMask | FRAME_UNDECORATED_FLAGS)
-                                 ^ FRAME_DECORATED_FLAGS)];
-        }
+      if (!FRAME_UNDECORATED (f))
+        [view createToolbar: f];
+
+      if ([oldWindow isKeyWindow])
+        [newWindow makeKeyAndOrderFront:NSApp];
 
-      /* At this point it seems we don't have an active NSResponder,
-         so some key presses (TAB) are swallowed by the system.  */
-      [window makeFirstResponder: view];
+      [newWindow setIsVisible:[oldWindow isVisible]];
+      if ([oldWindow isMiniaturized])
+        [newWindow miniaturize:NSApp];
+
+      [oldWindow close];
 
       unblock_input ();
     }
 }
-#endif /* NS_IMPL_COCOA */
 
 void
 ns_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object 
old_value)
@@ -7259,12 +7250,6 @@ not_in_argv (NSString *arg)
 
 - (instancetype) initFrameFromEmacs: (struct frame *)f
 {
-  NSRect r, wr;
-  Lisp_Object tem;
-  EmacsWindow *win;
-  NSColor *col;
-  NSString *name;
-
   NSTRACE ("[EmacsView initFrameFromEmacs:]");
   NSTRACE_MSG ("cols:%d lines:%d", f->text_cols, f->text_lines);
 
@@ -7286,9 +7271,9 @@ not_in_argv (NSString *arg)
   nonfs_window = nil;
 
   ns_userRect = NSMakeRect (0, 0, 0, 0);
-  r = NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
-                 FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines));
-  [self initWithFrame: r];
+  [self initWithFrame:
+          NSMakeRect (0, 0, FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
+                      FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, f->text_lines))];
   [self setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
 
   FRAME_NS_VIEW (f) = self;
@@ -7298,37 +7283,7 @@ not_in_argv (NSString *arg)
   maximizing_resize = NO;
 #endif
 
-  win = [[EmacsWindow alloc]
-            initWithContentRect: r
-                      styleMask: (FRAME_UNDECORATED (f)
-                                  ? FRAME_UNDECORATED_FLAGS
-                                  : FRAME_DECORATED_FLAGS)
-                        backing: NSBackingStoreBuffered
-                          defer: YES];
-
-#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
-  if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_7)
-#endif
-    if (FRAME_PARENT_FRAME (f))
-      [win 
setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
-    else
-      [win setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
-#endif
-
-  wr = [win frame];
-  bwidth = f->border_width = wr.size.width - r.size.width;
-
-  [win setAcceptsMouseMovedEvents: YES];
-  [win setDelegate: self];
-#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
-#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
-  if ([win respondsToSelector: @selector(useOptimizedDrawing:)])
-#endif
-    [win useOptimizedDrawing: YES];
-#endif
-
-  [[win contentView] addSubview: self];
+  [[EmacsWindow alloc] initWithEmacsFrame:f];
 
 #ifdef NS_IMPL_COCOA
   /* These settings mean AppKit will retain the contents of the frame
@@ -7344,65 +7299,10 @@ not_in_argv (NSString *arg)
   if (ns_drag_types)
     [self registerForDraggedTypes: ns_drag_types];
 
-  tem = f->name;
-  name = NILP (tem) ? @"Emacs" : [NSString stringWithLispString:tem];
-  [win setTitle: name];
-
   /* toolbar support */
   if (! FRAME_UNDECORATED (f))
     [self createToolbar: f];
 
-
-  [win setAppearance];
-
-#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
-  if ([win respondsToSelector: @selector(titlebarAppearsTransparent)])
-    win.titlebarAppearsTransparent = FRAME_NS_TRANSPARENT_TITLEBAR (f);
-#endif
-
-  tem = f->icon_name;
-  if (!NILP (tem))
-    [win setMiniwindowTitle:
-           [NSString stringWithLispString:tem]];
-
-  if (FRAME_PARENT_FRAME (f) != NULL)
-    {
-      NSWindow *parent = [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window];
-      [parent addChildWindow: win
-                     ordered: NSWindowAbove];
-    }
-
-  if (FRAME_Z_GROUP (f) != z_group_none)
-      win.level = NSNormalWindowLevel
-        + (FRAME_Z_GROUP_BELOW (f) ? -1 : 1);
-
-  {
-    NSScreen *screen = [win screen];
-
-    if (screen != 0)
-      {
-        NSPoint pt = NSMakePoint
-          (IN_BOUND (-SCREENMAX, f->left_pos
-                     + NS_PARENT_WINDOW_LEFT_POS (f), SCREENMAX),
-           IN_BOUND (-SCREENMAX,
-                     NS_PARENT_WINDOW_TOP_POS (f) - f->top_pos,
-                     SCREENMAX));
-
-        [win setFrameTopLeftPoint: pt];
-
-        NSTRACE_RECT ("new frame", [win frame]);
-      }
-  }
-
-  [win makeFirstResponder: self];
-
-  col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
-                                (FACE_FROM_ID (emacsframe, DEFAULT_FACE_ID)),
-                                emacsframe);
-  [win setBackgroundColor: col];
-  if ([col alphaComponent] != (EmacsCGFloat) 1.0)
-    [win setOpaque: NO];
-
 #if !defined (NS_IMPL_COCOA) \
   || MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
 #if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
@@ -7420,14 +7320,6 @@ not_in_argv (NSString *arg)
          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.  */
-#ifdef NS_IMPL_COCOA
-  if ([win respondsToSelector: @selector(setTabbingMode:)])
-    [win setTabbingMode: NSWindowTabbingModeDisallowed];
-#endif
-
   ns_window_num++;
   return self;
 }
@@ -7817,7 +7709,7 @@ not_in_argv (NSString *arg)
 
 - (void)toggleFullScreen: (id)sender
 {
-  NSWindow *w, *fw;
+  EmacsWindow *w, *fw;
   BOOL onFirstScreen;
   struct frame *f;
   NSRect r, wr;
@@ -7836,7 +7728,7 @@ not_in_argv (NSString *arg)
       return;
     }
 
-  w = [self window];
+  w = (EmacsWindow *)[self window];
   onFirstScreen = [[w screen] isEqual:[[NSScreen screens] objectAtIndex:0]];
   f = emacsframe;
   wr = [w frame];
@@ -7871,27 +7763,9 @@ not_in_argv (NSString *arg)
 #endif
         }
 
-      fw = [[EmacsFSWindow alloc]
-                       initWithContentRect:[w contentRectForFrameRect:wr]
-                                 styleMask:NSWindowStyleMaskBorderless
-                                   backing:NSBackingStoreBuffered
-                                     defer:YES
-                                    screen:screen];
-
-      [fw setContentView:[w contentView]];
-      [fw setTitle:[w title]];
-      [fw setDelegate:self];
-      [fw setAcceptsMouseMovedEvents: YES];
-#if !defined (NS_IMPL_COCOA) \
-  || MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
-#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
-      if ([fw respondsToSelector: @selector(useOptimizedDrawing:)])
-#endif
-        [fw useOptimizedDrawing: YES];
-#endif
-      [fw setBackgroundColor: col];
-      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
-        [fw setOpaque: NO];
+      fw = [[EmacsWindow alloc] initWithEmacsFrame:emacsframe
+                                        fullscreen:YES
+                                            screen:screen];
 
       f->border_width = 0;
 
@@ -7899,7 +7773,6 @@ not_in_argv (NSString *arg)
 
       [self windowWillEnterFullScreen];
       [fw makeKeyAndOrderFront:NSApp];
-      [fw makeFirstResponder:self];
       [w orderOut:self];
       r = [fw frameRectForContentRect:[screen frame]];
       [fw setFrame: r display:YES animate:ns_use_fullscreen_animation];
@@ -7926,7 +7799,7 @@ not_in_argv (NSString *arg)
       if ([col alphaComponent] != (EmacsCGFloat) 1.0)
         [w setOpaque: NO];
 
-      f->border_width = bwidth;
+      f->border_width = [w borderWidth];
 
       // To do: consider using [NSNotificationCenter postNotificationName:] to
       // send notifications.
@@ -8503,6 +8376,133 @@ not_in_argv (NSString *arg)
 
 @implementation EmacsWindow
 
+
+- (instancetype) initWithEmacsFrame:(struct frame *)f
+{
+  return [self initWithEmacsFrame:f fullscreen:NO screen:nil];
+}
+
+
+- (instancetype) initWithEmacsFrame:(struct frame *)f
+                         fullscreen:(BOOL)fullscreen
+                             screen:(NSScreen *)screen
+{
+  NSWindowStyleMask styleMask;
+
+  NSTRACE ("[EmacsWindow initWithEmacsFrame:fullscreen:screen:]");
+
+  if (fullscreen)
+    styleMask = NSWindowStyleMaskBorderless;
+  else if (FRAME_UNDECORATED (f))
+    styleMask = FRAME_UNDECORATED_FLAGS;
+  else
+    styleMask = FRAME_DECORATED_FLAGS;
+
+
+  self = [super initWithContentRect:
+                  NSMakeRect (0, 0,
+                              FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, f->text_cols),
+                              FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 
f->text_lines))
+                          styleMask:styleMask
+                            backing:NSBackingStoreBuffered
+                              defer:YES
+                             screen:screen];
+  if (self)
+    {
+      NSString *name;
+      NSColor *col;
+      NSScreen *screen = [self screen];
+      EmacsView *view = FRAME_NS_VIEW (f);
+
+      [self setDelegate:view];
+      [[self contentView] addSubview:view];
+      [self makeFirstResponder:view];
+
+#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+#if MAC_OS_X_VERSION_MAX_ALLOWED > 1090
+      if ([self respondsToSelector: @selector(useOptimizedDrawing:)])
+#endif
+        [self useOptimizedDrawing:YES];
+#endif
+
+      [self setAcceptsMouseMovedEvents:YES];
+
+      name = NILP (f->name) ? @"Emacs" : [NSString 
stringWithLispString:f->name];
+      [self setTitle:name];
+
+      if (!NILP (f->icon_name))
+        [self setMiniwindowTitle:
+                [NSString stringWithLispString:f->icon_name]];
+
+      [self setAppearance];
+
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
+      if ([self respondsToSelector:@selector(titlebarAppearsTransparent)])
+        [self setTitlebarAppearsTransparent:FRAME_NS_TRANSPARENT_TITLEBAR (f)];
+#endif
+
+      #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+      if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_7)
+#endif
+        if (FRAME_PARENT_FRAME (f))
+          [self 
setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
+        else
+          [self 
setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+#endif
+
+      if (FRAME_PARENT_FRAME (f) != NULL)
+        {
+          NSWindow *parent = [FRAME_NS_VIEW (FRAME_PARENT_FRAME (f)) window];
+          [parent addChildWindow:self
+                         ordered:NSWindowAbove];
+        }
+
+      if (FRAME_Z_GROUP (f) != z_group_none)
+        [self setLevel:NSNormalWindowLevel + (FRAME_Z_GROUP_BELOW (f) ? -1 : 
1)];
+
+      if (screen != 0)
+        {
+          NSPoint pt = NSMakePoint
+            (IN_BOUND (-SCREENMAX, f->left_pos
+                       + NS_PARENT_WINDOW_LEFT_POS (f), SCREENMAX),
+             IN_BOUND (-SCREENMAX,
+                       NS_PARENT_WINDOW_TOP_POS (f) - f->top_pos,
+                       SCREENMAX));
+
+          [self setFrameTopLeftPoint:pt];
+
+          NSTRACE_RECT ("new frame", [self frame]);
+        }
+
+      f->border_width = [self borderWidth];
+
+      col = ns_lookup_indexed_color (NS_FACE_BACKGROUND
+                                     (FACE_FROM_ID (f, DEFAULT_FACE_ID)),
+                                     f);
+      [self setBackgroundColor:col];
+      if ([col alphaComponent] != (EmacsCGFloat) 1.0)
+        [self setOpaque:NO];
+
+      /* 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.  */
+#ifdef NS_IMPL_COCOA
+      if ([self respondsToSelector:@selector(setTabbingMode:)])
+        [self setTabbingMode:NSWindowTabbingModeDisallowed];
+#endif
+    }
+
+  return self;
+}
+
+
+- (NSInteger) borderWidth
+{
+  return NSWidth ([self frame]) - NSWidth ([[self contentView] frame]);
+}
+
+
 /* It seems the only way to reorder child frames is by removing them
    from the parent and then reattaching them in the correct order.  */
 
@@ -8912,22 +8912,15 @@ nswindow_orderedIndex_sort (id w1, id w2, void *c)
 {
   return !FRAME_NO_ACCEPT_FOCUS (((EmacsView *)[self delegate])->emacsframe);
 }
-@end /* EmacsWindow */
-
-
-@implementation EmacsFSWindow
-
-- (BOOL)canBecomeKeyWindow
-{
-  return YES;
-}
 
 - (BOOL)canBecomeMainWindow
+  /* Required for fullscreen and undecorated windows.  */
 {
   return YES;
 }
 
-@end
+@end /* EmacsWindow */
+
 
 /* ==========================================================================
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]