Mac平台下,如何为SDL_CreateWindow创建的无边框SDL2窗口添加圆角?
Hey there! Great question—SDL doesn’t include a native API for setting rounded corners on borderless windows, but since SDL wraps macOS’s Cocoa framework under the hood, we can tap into native Objective-C APIs to make this work. Here’s a step-by-step guide:
Prerequisites
- Target macOS 10.10 or later (the
setCornerRadiusAPI was introduced here) - Your project must link against the Cocoa framework
- If mixing C/C++ with Objective-C, use
.mmas your source file extension (to enable Objective-C++ compilation)
Step-by-Step Implementation
1. Include Required Headers
You’ll need SDL’s window management headers plus Cocoa’s framework headers:
#include <SDL2/SDL.h> #include <SDL2/SDL_syswm.h> #import <Foundation/Foundation.h> #import <AppKit/AppKit.h>
2. Initialize SDL and Create Your Borderless Window
Standard SDL setup, with code added to fetch the native Cocoa window handle:
int main(int argc, char* argv[]) { // Initialize SDL video subsystem if (SDL_Init(SDL_INIT_VIDEO) != 0) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "SDL init failed: %s", SDL_GetError()); return 1; } // Create borderless window SDL_Window* window = SDL_CreateWindow( "Rounded Borderless Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_BORDERLESS ); if (!window) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to create window: %s", SDL_GetError()); SDL_Quit(); return 1; }
3. Fetch the Native NSWindow Pointer
Use SDL_GetWindowWMInfo() to access the underlying Cocoa NSWindow instance:
SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); // Critical: Initialize version info before use if (!SDL_GetWindowWMInfo(window, &wmInfo)) { SDL_LogError(SDL_LOG_CATEGORY_ERROR, "Failed to get window WM info: %s", SDL_GetError()); SDL_DestroyWindow(window); SDL_Quit(); return 1; } // Convert the void* handle to an NSWindow* (use __bridge to avoid ARC issues) NSWindow* nsWindow = (__bridge NSWindow*)wmInfo.info.cocoa.window;
4. Set the Corner Radius
Call Cocoa’s setCornerRadius: method to apply rounded corners. Adjust the value to your preference:
// Set corner radius (20.0 is a reasonable starting point) [nsWindow setCornerRadius:20.0]; // Optional: If your window has transparent content, set a clear background // [nsWindow setBackgroundColor:[NSColor clearColor]];
5. Run Your Main Loop
Finish with standard SDL cleanup:
// Main event loop bool running = true; SDL_Event event; while (running) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { running = false; } } // Add your rendering logic here SDL_Delay(16); // ~60 FPS } // Cleanup SDL_DestroyWindow(window); SDL_Quit(); return 0; }
Compilation Notes
When compiling, link against the Cocoa framework and use SDL’s config flags:
gcc -o rounded_window rounded_window.mm `sdl2-config --cflags --libs` -framework Cocoa
Key Notes
- Version Compatibility: If you need to support macOS versions older than 10.10, wrap the
setCornerRadiuscall in a version check:if (@available(macOS 10.10, *)) { [nsWindow setCornerRadius:20.0]; } - Content Clipping: The
NSWindow’s corner radius will automatically clip your SDL-rendered content, so you don’t need to adjust your rendering code unless you’re drawing outside the window bounds.
内容的提问来源于stack exchange,提问作者John

