From 1f933e8c108568782cf76a0a891defc68643c7a4 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Thu, 28 Sep 2023 16:10:05 -0700 Subject: [PATCH] Mac: Fix Drawable clipping to bounds on macOS Sonoma --- src/Eto.Mac/Drawing/GraphicsHandler.cs | 7 ++++++- src/Eto.Mac/Forms/Cells/DrawableCellHandler.cs | 4 ++-- src/Eto.Mac/Forms/Controls/DrawableHandler.cs | 12 +++--------- src/Eto.Mac/Forms/Printing/PrintDocumentHandler.cs | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Eto.Mac/Drawing/GraphicsHandler.cs b/src/Eto.Mac/Drawing/GraphicsHandler.cs index 93dc237d6..9d360ba68 100644 --- a/src/Eto.Mac/Drawing/GraphicsHandler.cs +++ b/src/Eto.Mac/Drawing/GraphicsHandler.cs @@ -83,13 +83,18 @@ public GraphicsHandler() } #if OSX - public GraphicsHandler(NSView view, NSGraphicsContext graphicsContext, float height) + public GraphicsHandler(NSView view, NSGraphicsContext graphicsContext, float height, CGRect? dirtyRect) { DisplayView = view; this.height = height; var flipped = view?.IsFlipped ?? false; this.graphicsContext = graphicsContext.IsFlipped ? graphicsContext : NSGraphicsContext.FromCGContext(graphicsContext.CGContext, true); Control = this.graphicsContext.CGContext; + + // Clip to bounds otherwise you can draw outside the control on macOS Sonoma + if (dirtyRect != null) + Control.ClipToRect(dirtyRect.Value); + InitializeContext(!flipped); } diff --git a/src/Eto.Mac/Forms/Cells/DrawableCellHandler.cs b/src/Eto.Mac/Forms/Cells/DrawableCellHandler.cs index b923cea7a..2cc588ec6 100644 --- a/src/Eto.Mac/Forms/Cells/DrawableCellHandler.cs +++ b/src/Eto.Mac/Forms/Cells/DrawableCellHandler.cs @@ -69,7 +69,7 @@ public override void DrawInteriorWithFrame(CGRect cellFrame, NSView inView) } var handler = Handler; - var graphicsHandler = new GraphicsHandler(inView, nscontext, (float)cellFrame.Height); + var graphicsHandler = new GraphicsHandler(inView, nscontext, (float)cellFrame.Height, cellFrame); using (var graphics = new Graphics(graphicsHandler)) { var state = Highlighted ? CellStates.Selected : CellStates.None; @@ -167,7 +167,7 @@ public override void DrawRect(CGRect dirtyRect) var handler = Handler; if (handler == null) return; - var graphicsHandler = new GraphicsHandler(this, nscontext, (float)cellFrame.Height); + var graphicsHandler = new GraphicsHandler(this, nscontext, (float)cellFrame.Height, cellFrame); using (var graphics = new Graphics(graphicsHandler)) { var rowView = this.Superview as NSTableRowView; diff --git a/src/Eto.Mac/Forms/Controls/DrawableHandler.cs b/src/Eto.Mac/Forms/Controls/DrawableHandler.cs index 013cde650..c94f6a39a 100644 --- a/src/Eto.Mac/Forms/Controls/DrawableHandler.cs +++ b/src/Eto.Mac/Forms/Controls/DrawableHandler.cs @@ -36,12 +36,8 @@ public override void DrawRect(CGRect dirtyRect) if (!IsFlipped) dirty.Y = bounds.Height - dirty.Y - dirty.Height; - if (dirty.X % 1.0f > 0f) - dirty.Width += 1; - if (dirty.Y % 1.0f > 0f) - dirty.Height += 1; ApplicationHandler.QueueResizing = true; - drawable.DrawRegion(Rectangle.Ceiling(dirty)); + drawable.DrawRegion(dirty); ApplicationHandler.QueueResizing = false; } @@ -120,14 +116,12 @@ public override void Invalidate(Rectangle rect, bool invalidateChildren) base.Invalidate(rect, invalidateChildren); } - void DrawRegion(Rectangle rect) + void DrawRegion(RectangleF rect) { var context = NSGraphicsContext.CurrentContext; if (context != null) { - var handler = new GraphicsHandler(Control, context, (float)Control.Frame.Height); - // macOS Sonoma can draw outside the bounds of the NSView, so clip to the drawing rectangle - handler.Control.ClipToRect(rect.ToNS()); + var handler = new GraphicsHandler(Control, context, (float)Control.Frame.Height, rect.ToNS()); using (var graphics = new Graphics(handler)) { diff --git a/src/Eto.Mac/Forms/Printing/PrintDocumentHandler.cs b/src/Eto.Mac/Forms/Printing/PrintDocumentHandler.cs index a7465f498..60df5604d 100644 --- a/src/Eto.Mac/Forms/Printing/PrintDocumentHandler.cs +++ b/src/Eto.Mac/Forms/Printing/PrintDocumentHandler.cs @@ -67,7 +67,7 @@ public override void DrawRect(CGRect dirtyRect) var height = Frame.Height; var pageRect = RectForPage(operation.CurrentPage); - using (var graphics = new Graphics(new GraphicsHandler(this, context, (float)height))) + using (var graphics = new Graphics(new GraphicsHandler(this, context, (float)height, pageRect))) { graphics.TranslateTransform((float)pageRect.X, (float)(height-pageRect.Y-pageRect.Height)); Handler.Callback.OnPrintPage(Handler.Widget, new PrintPageEventArgs(graphics, operation.PrintInfo.ImageablePageBounds.Size.ToEto(), (int)operation.CurrentPage - 1));