Transparent NSWindow using subclasses of NSWindow and NSView

This is a quick example of how to get a Transparent NSWindow using a subclassed NSWindow class and a subclassed NSView.

This is in response to a stackoverflow users request I post the source code. Which I have done here in context.

(Originally it had also had a webview which was related to the question but was not essential in any way in this example so it has been removed.)

Transparent Window with Controls and Labels overlaying it. If you click any where in the transparency the mouse will click the object behind the window. And the objects Application will become the active one.

transparentWindow2

1, In the AppDelegate’s Header .


//

//  AppDelegate.h

//

//  Created by Mark Hunte on 19/01/2014.

//  Copyright (c) 2014 Mark Hunte. All rights reserved.

//

#import <Cocoa/Cocoa.h>

#import <WebKit/WebKit.h>

@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

@end


 

2, In the AppDelegate .M

AppDelegate.m


 

//

//  AppDelegate.m

//  Transparent

//

//  Created by Mark Hunte on 19/01/2014.

//  Copyright (c) 2014 Mark Hunte. All rights reserved.

//

#import “AppDelegate.h”

@implementation AppDelegate

– (void)applicationDidFinishLaunching:(NSNotification *)aNotification

{

    // Insert code here to initialize your application

}

-(void)awakeFromNib{

 

}

@end


3,  Subclass the NSWindow using:

[self setOpaque:NO]; [self setHasShadow:NO];

And styleMask of you choice along with any other options you want.

Here I gave it a Title bar.

*( If you do not want a title bar but want to move it around. You would have to override : – (BOOL)canBecomeKeyWindow And use: – (void)mouseDown:(NSEvent *)theEvent {
– (void)mouseDragged:(NSEvent )theEvent { To track the window movement and location. )


 

MyWindow.h

//  MyView.h

//

//  Created by markhunte on 13/12/2010.

//  Copyright 2010 markosx.com. All rights reserved.

//

#import <Cocoa/Cocoa.h>

@interface MyView : NSView{

}

– (id)initWithFrame:(NSRect)frameRect;

– (void)drawRect:(NSRect)rect;

@end


 

MyWindow.m

//  MyWindow.m

//

//  Created by markhunte on 12/12/2010.

//  Copyright 2010 __markosx.com__. All rights reserved.

//

#import “MyWindow.h”

@implementation MyWindow

– (id)initWithContentRect:(NSRect)contentRect styleMask:( unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {

        self = [super initWithContentRect:contentRect styleMask : NSTitledWindowMask backing :NSBackingStoreBuffered defer:NO ];

        if (self)

        {

            [self setOpaque:NO];

            [self setHasShadow:NO];

        }

        return self;

}

@end


 

4, Subclass the NSWindow’s View using:

[[NSColor clearColor] set];

NSRectFill([self frame]); in its - (void)drawRect:(NSRect)rect

MyView.h


//  MyView.h

//

//  Created by markhunte on 13/12/2010.

//  Copyright 2010 markosx.com. All rights reserved.

//

#import <Cocoa/Cocoa.h>

@interface MyView : NSView{

}

– (id)initWithFrame:(NSRect)frameRect;

– (void)drawRect:(NSRect)rect;

@end


 

MyView.m


//  MyView.m

//

//  Created by markhunte on 13/12/2010.

//  Copyright 2010 markosx.com. All rights reserved.

//

#import “MyView.h”

@implementation MyView

– (id)initWithFrame:(NSRect)frameRect

{

    self = [super initWithFrame:frameRect];

    return self;

}

– (void)drawRect:(NSRect)rect

{

[[NSColor clearColor] set];

NSRectFill([selfframe]);

}

@end


How things look In IB

transparentWindow1

I have placed some labels in the layout just for illustration.

Build and Run.

 

I will probably expand on this to show how to redraw  the window with a shape and no title bar.

 

Download Project .  Download “Transparent NSWindow Project” Transparent-Project.zip – Downloaded 8999 times – 48.65 KB

7 Replies to “Transparent NSWindow using subclasses of NSWindow and NSView”

  1. For contemporary macOSs, add this:

    [self setBackgroundColor:[NSColor clearColor]];

    right after this:

    [self setOpaque:NO];
    [self setHasShadow:NO];

    The project will work for layer backed apps, too.

    TL/DR

    Historically, all views drew into the same buffer. So, internal to AppKit, NSWindow would draw its background color into the buffer. Then the app would have its chance to draw — and by drawing clear, it could clear through and make the cumulative drawn result transparent. However, with layers, things are more complex, because now a transparently drawn view simply shows what is underneath it, which is the background color of the window.

  2. Hi Jeff, I think that was what the person on stack overflow was after. Although I never really understood the point. If you need a copy of the old project?. I can dig it out for you.

  3. Hi Mark — thanks for your followup comments! Ironically your original use of a web view is what sent me to your article in the first place 🙂 I am too late now, but I have a feeling WebView’s drawsBackground could be used to hide the background of the web view without hiding anything actually displayed inside it.

  4. Jeff, It did always actually bug me that the original question wanted a transparent webview which made no sense to me at the time. So thanks for prompting me in removing an itch. 🙂

  5. Hi Jeff,

    Yes you are correct. That is why in the post I wrote “Also the use of a webview is related to the question but is not essential in any way apart from it’s Alpha setting in this example.

    Lazy of me to keep it in from my original and I may remove it when I get a chance but it does no harm here in this simple example.

  6. In your example, there’s nothing actually being loaded into the WebView. Since the WebView has alphaValue of 0, won’t it be impossible to see anything in the HTML loaded into the WebView?

  7. Thanks for the post. I couldn’t figure out why my transperancy window was not drawing under views properly. All I had to do was [self setHasShadow:NO]; for the window.

    Couldn’t figure out the shadows were the problem.

Comments are closed.