[gtk/wip/chergert/quartz4u] start on cairo toplevel view



commit ff7af543b94309e555290b9afe9622c7970ddd15
Author: Christian Hergert <chergert redhat com>
Date:   Thu Apr 30 17:01:39 2020 -0700

    start on cairo toplevel view

 gdk/macos/GdkMacosBaseView.c        | 105 ++++++++++++++++++++++++++++++++++++
 gdk/macos/GdkMacosBaseView.h        |  40 ++++++++++++++
 gdk/macos/GdkMacosCairoView.c       |  36 +++++++++++++
 gdk/macos/GdkMacosCairoView.h       |  31 +++++++++++
 gdk/macos/GdkMacosWindow.c          |  71 ++++++++++++------------
 gdk/macos/gdkmacosdisplay-private.h |   5 ++
 gdk/macos/gdkmacosdisplay.c         |  14 +++++
 gdk/macos/gdkmacossurface-private.h |   3 +-
 gdk/macos/gdkmacossurface.c         |  19 +++++++
 gdk/macos/meson.build               |   3 ++
 10 files changed, 290 insertions(+), 37 deletions(-)
---
diff --git a/gdk/macos/GdkMacosBaseView.c b/gdk/macos/GdkMacosBaseView.c
new file mode 100644
index 0000000000..c9e9db5a3b
--- /dev/null
+++ b/gdk/macos/GdkMacosBaseView.c
@@ -0,0 +1,105 @@
+/* GdkMacosBaseView.c
+ *
+ * Copyright © 2020 Red Hat, Inc.
+ * Copyright © 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#import "GdkMacosBaseView.h"
+
+#include "gdkinternals.h"
+
+@implementation GdkMacosBaseView
+
+-(id)initWithFrame:(NSRect)frameRect
+{
+  if ((self = [super initWithFrame: frameRect]))
+    {
+      markedRange = NSMakeRange (NSNotFound, 0);
+      selectedRange = NSMakeRange (NSNotFound, 0);
+    }
+
+  return self;
+}
+
+-(void)setNeedsInvalidateShadow: (BOOL)invalidate
+{
+  needsInvalidateShadow = invalidate;
+}
+
+/* For information on setting up tracking rects properly, see here:
+ * http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/EventOverview.pdf
+ */
+-(void)updateTrackingRect
+{
+  NSRect rect;
+
+  if (trackingRect)
+    {
+      [self removeTrackingRect: trackingRect];
+      trackingRect = 0;
+    }
+
+  /* Note, if we want to set assumeInside we can use:
+   * NSPointInRect ([[self window] convertScreenToBase:[NSEvent mouseLocation]], rect)
+   */
+
+  rect = [self bounds];
+  trackingRect = [self addTrackingRect: rect
+                                            owner: self
+                                         userData: nil
+                                     assumeInside: NO];
+}
+
+-(NSTrackingRectTag)trackingRect
+{
+  return trackingRect;
+}
+
+-(void)viewDidMoveToWindow
+{
+  if (![self window]) /* We are destroyed already */
+    return;
+
+  [self updateTrackingRect];
+}
+
+-(void)viewWillMoveToWindow: (NSWindow *)newWindow
+{
+  if (newWindow == nil && trackingRect)
+    {
+      [self removeTrackingRect: trackingRect];
+      trackingRect = 0;
+    }
+}
+
+-(void)setFrame: (NSRect)frame
+{
+  [super setFrame: frame];
+
+  if ([self window])
+    [self updateTrackingRect];
+}
+
+-(BOOL)isOpaque
+{
+  return NO;
+}
+
+@end
diff --git a/gdk/macos/GdkMacosBaseView.h b/gdk/macos/GdkMacosBaseView.h
new file mode 100644
index 0000000000..a3c6c05e40
--- /dev/null
+++ b/gdk/macos/GdkMacosBaseView.h
@@ -0,0 +1,40 @@
+/* GdkMacosBaseView.h
+ *
+ * Copyright © 2020 Red Hat, Inc.
+ * Copyright © 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#import <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+
+#include <gdk/gdk.h>
+
+#include "gdkmacossurface.h"
+
+@interface GdkMacosBaseView : NSView
+{
+  NSTrackingRectTag trackingRect;
+  BOOL needsInvalidateShadow;
+  NSRange markedRange;
+  NSRange selectedRange;
+}
+
+-(void)setNeedsInvalidateShadow: (BOOL)invalidate;
+-(NSTrackingRectTag)trackingRect;
+
+@end
diff --git a/gdk/macos/GdkMacosCairoView.c b/gdk/macos/GdkMacosCairoView.c
new file mode 100644
index 0000000000..ffb47a924f
--- /dev/null
+++ b/gdk/macos/GdkMacosCairoView.c
@@ -0,0 +1,36 @@
+/* GdkMacosCairoView.c
+ *
+ * Copyright © 2020 Red Hat, Inc.
+ * Copyright © 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#import "GdkMacosCairoView.h"
+
+#include "gdkinternals.h"
+
+@implementation GdkMacosCairoView
+
+-(void)dealloc
+{
+  g_clear_pointer (&self->surface, cairo_surface_destroy);
+  [super dealloc];
+}
+
+@end
diff --git a/gdk/macos/GdkMacosCairoView.h b/gdk/macos/GdkMacosCairoView.h
new file mode 100644
index 0000000000..a7b39bccfe
--- /dev/null
+++ b/gdk/macos/GdkMacosCairoView.h
@@ -0,0 +1,31 @@
+/* GdkMacosCairoView.h
+ *
+ * Copyright © 2020 Red Hat, Inc.
+ * Copyright © 2005-2007 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <cairo.h>
+
+#import "GdkMacosBaseView.h"
+
+@interface GdkMacosCairoView : GdkMacosBaseView
+{
+  cairo_surface_t *surface;
+}
+
+@end
diff --git a/gdk/macos/GdkMacosWindow.c b/gdk/macos/GdkMacosWindow.c
index b62a706bed..4567720733 100644
--- a/gdk/macos/GdkMacosWindow.c
+++ b/gdk/macos/GdkMacosWindow.c
@@ -23,6 +23,8 @@
 
 #include <gdk/gdk.h>
 
+#import "GdkMacosBaseView.h"
+#import "GdkMacosCairoView.h"
 #import "GdkMacosWindow.h"
 
 #include "gdkmacossurface-private.h"
@@ -145,9 +147,8 @@
     {
     case NSEventTypeLeftMouseUp:
     {
-      double time = ((double)[event timestamp]) * 1000.0;
-
 #if 0
+      double time = ((double)[event timestamp]) * 1000.0;
       _gdk_quartz_events_break_all_grabs (time);
 #endif
 
@@ -176,13 +177,9 @@
 
 -(void)checkSendEnterNotify
 {
-#if 0
-  GdkSurface *window = [[self contentView] gdkSurface];
-  GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
-
-  /* When a new window has been created, and the mouse
-   * is in the window area, we will not receive an NSMouseEntered
-   * event.  Therefore, we synthesize an enter notify event manually.
+  /* When a new window has been created, and the mouse is in the window
+   * area, we will not receive an NSEventTypeMouseEntered event.
+   * Therefore, we synthesize an enter notify event manually.
    */
   if (!initialPositionKnown)
     {
@@ -190,22 +187,22 @@
 
       if (NSPointInRect ([NSEvent mouseLocation], [self frame]))
         {
+          GdkMacosBaseView *view = (GdkMacosBaseView *)[self contentView];
           NSEvent *event;
 
-          event = [NSEvent enterExitEventWithType: NSMouseEntered
+          event = [NSEvent enterExitEventWithType: NSEventTypeMouseEntered
                                          location: [self mouseLocationOutsideOfEventStream]
                                     modifierFlags: 0
                                         timestamp: [[NSApp currentEvent] timestamp]
-                                     windowNumber: [impl->toplevel windowNumber]
+                                     windowNumber: [self windowNumber]
                                           context: NULL
                                       eventNumber: 0
-                                   trackingNumber: [impl->view trackingRect]
+                                   trackingNumber: [view trackingRect]
                                          userData: nil];
 
           [NSApp postEvent:event atStart:NO];
         }
     }
-#endif
 }
 
 -(void)windowDidMove:(NSNotification *)aNotification
@@ -243,49 +240,48 @@
 
 -(void)windowDidResize:(NSNotification *)aNotification
 {
-#if 0
-  NSRect content_rect = [self contentRectForFrameRect:[self frame]];
-  GdkSurface *window = [[self contentView] gdkSurface];
+  NSRect content_rect;
+  GdkSurface *surface;
+  GdkDisplay *display;
   GdkEvent *event;
-  GdkSurfaceImplQuartz *impl = GDK_SURFACE_IMPL_QUARTZ (window->impl);
-  gboolean maximized = gdk_surface_get_state (window) & GDK_SURFACE_STATE_MAXIMIZED;
+  gboolean maximized;
+
+  surface = GDK_SURFACE (self->gdkSurface);
+  display = gdk_surface_get_display (surface);
+
+  content_rect = [self contentRectForFrameRect:[self frame]];
+  maximized = (surface->state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
 
   /* see same in windowDidMove */
   if (maximized && !inMaximizeTransition && !NSEqualRects (lastMaximizedFrame, [self frame]))
-    {
-      gdk_synthesize_surface_state (window,
-                                   GDK_SURFACE_STATE_MAXIMIZED,
-                                   0);
-    }
+    gdk_synthesize_surface_state (surface, GDK_SURFACE_STATE_MAXIMIZED, 0);
 
-  window->width = content_rect.size.width;
-  window->height = content_rect.size.height;
+  surface->width = content_rect.size.width;
+  surface->height = content_rect.size.height;
 
   /* Certain resize operations (e.g. going fullscreen), also move the
    * origin of the window.
    */
-  _gdk_quartz_surface_update_position (window);
+  _gdk_macos_surface_update_position (GDK_MACOS_SURFACE (surface));
 
-  [[self contentView] setFrame:NSMakeRect (0, 0, window->width, window->height)];
+  [[self contentView] setFrame:NSMakeRect (0, 0, surface->width, surface->height)];
 
-  _gdk_surface_update_size (window);
+  _gdk_surface_update_size (surface);
 
   /* Synthesize a configure event */
-  event = gdk_event_new (GDK_CONFIGURE);
-  event->configure.window = g_object_ref (window);
-  event->configure.x = window->x;
-  event->configure.y = window->y;
-  event->configure.width = window->width;
-  event->configure.height = window->height;
+  event = gdk_configure_event_new (surface,
+                                   content_rect.size.width,
+                                   content_rect.size.height);
 
-  _gdk_event_queue_append (gdk_display_get_default (), event);
+  _gdk_event_queue_append (display, event);
 
   [self checkSendEnterNotify];
-#endif
 }
 
 -(id)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)styleMask 
backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen
 {
+  GdkMacosCairoView *view;
+
   self = [super initWithContentRect:contentRect
                          styleMask:styleMask
                            backing:backingType
@@ -296,6 +292,9 @@
   [self setDelegate:nil];
   [self setReleasedWhenClosed:YES];
 
+  view = [[GdkMacosCairoView alloc] initWithFrame:contentRect];
+  [self setContentView:view];
+
   return self;
 }
 
diff --git a/gdk/macos/gdkmacosdisplay-private.h b/gdk/macos/gdkmacosdisplay-private.h
index b7503eed33..7d9fd6a55b 100644
--- a/gdk/macos/gdkmacosdisplay-private.h
+++ b/gdk/macos/gdkmacosdisplay-private.h
@@ -34,6 +34,11 @@ void        _gdk_macos_display_to_display_coords            (GdkMacosDisplay *se
                                                              int              y,
                                                              int             *out_x,
                                                              int             *out_y);
+void        _gdk_macos_display_from_display_coords          (GdkMacosDisplay *self,
+                                                             int              x,
+                                                             int              y,
+                                                             int             *out_x,
+                                                             int             *out_y);
 NSScreen   *_gdk_macos_display_get_screen_at_display_coords (GdkMacosDisplay *self,
                                                              int              x,
                                                              int              y);
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c
index 9171a490f0..19bf94fbb7 100644
--- a/gdk/macos/gdkmacosdisplay.c
+++ b/gdk/macos/gdkmacosdisplay.c
@@ -441,6 +441,20 @@ _gdk_macos_display_to_display_coords (GdkMacosDisplay *self,
     *out_x = x + self->min_x;
 }
 
+void
+_gdk_macos_display_from_display_coords (GdkMacosDisplay *self,
+                                        int              x,
+                                        int              y,
+                                        int             *out_x,
+                                        int             *out_y)
+{
+  if (out_y)
+    *out_y = self->height - y + self->min_y;
+
+  if (out_x)
+    *out_x = x - self->min_x;
+}
+
 NSScreen *
 _gdk_macos_display_get_screen_at_display_coords (GdkMacosDisplay *self,
                                                  int              x,
diff --git a/gdk/macos/gdkmacossurface-private.h b/gdk/macos/gdkmacossurface-private.h
index 2990b17db6..e4319bf516 100644
--- a/gdk/macos/gdkmacossurface-private.h
+++ b/gdk/macos/gdkmacossurface-private.h
@@ -71,7 +71,8 @@ void               _gdk_macos_surface_resize                  (GdkMacosSurface
                                                                int                 width,
                                                                int                 height,
                                                                int                 scale);
-void               _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self);
+void               _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface    *self);
+void               _gdk_macos_surface_update_position         (GdkMacosSurface    *self);
 
 G_END_DECLS
 
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 70d5bceff5..b5b142f0b5 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -483,3 +483,22 @@ _gdk_macos_surface_update_fullscreen_state (GdkMacosSurface *self)
         gdk_synthesize_surface_state (GDK_SURFACE (self), GDK_SURFACE_STATE_FULLSCREEN, 0);
     }
 }
+
+void
+_gdk_macos_surface_update_position (GdkMacosSurface *self)
+{
+  GDK_BEGIN_MACOS_ALLOC_POOL;
+
+  GdkMacosSurfacePrivate *priv = gdk_macos_surface_get_instance_private (self);
+  GdkSurface *surface = GDK_SURFACE (self);
+  GdkDisplay *display = gdk_surface_get_display (surface);
+  NSRect frame_rect = [priv->window frame];
+  NSRect content_rect = [priv->window contentRectForFrameRect:frame_rect];
+
+  _gdk_macos_display_from_display_coords (GDK_MACOS_DISPLAY (display),
+                                          content_rect.origin.x,
+                                          content_rect.origin.y + content_rect.size.height,
+                                          &surface->x, &surface->y);
+
+  GDK_END_MACOS_ALLOC_POOL;
+}
diff --git a/gdk/macos/meson.build b/gdk/macos/meson.build
index 888fdbdbbb..2d06ca021a 100644
--- a/gdk/macos/meson.build
+++ b/gdk/macos/meson.build
@@ -12,6 +12,9 @@ gdk_macos_sources = files([
   'gdkmacossurface.c',
   'gdkmacostoplevelsurface.c',
 
+  'GdkMacosBaseView.c',
+  'GdkMacosCairoView.c',
+
   # 'GdkMacosView.c',
 ])
 


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