Skip to content

Commit

Permalink
Macos headerless window (#96)
Browse files Browse the repository at this point in the history
* check that drawing surface lock is successful

* add disable title bar

* bump skija

* make window handle accessible after `window.pack()` but before `window.setVisible(true)`

* rollback changes in demo App

* fix warning and return value in `lockDrawingSurface`

* reduce code duplication
  • Loading branch information
SergeevPavel committed Apr 26, 2021
1 parent beeb6e5 commit 7ea3f41
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 30 deletions.
10 changes: 5 additions & 5 deletions skiko/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
kotlin.code.style=official
deploy.version=0.0.0

dependencies.skija.git.commit=adbb8c2926045af424a2ff93f5f0110f965bdbbb
dependencies.skia.windows-x64=m89-109bfc9052/Skia-m89-109bfc9052-windows-Release-x64
dependencies.skia.linux-x64=m89-109bfc9052/Skia-m89-109bfc9052-linux-Release-x64
dependencies.skia.macos-x64=m89-109bfc9052/Skia-m89-109bfc9052-macos-Release-x64
dependencies.skia.macos-arm64=m89-109bfc9052/Skia-m89-109bfc9052-macos-Release-arm64
dependencies.skija.git.commit=a5d6dfd746b8a8ec2ef52ebea4baa53f299d080c
dependencies.skia.windows-x64=m90-adbb69cd7f-2/Skia-m90-adbb69cd7f-2-windows-Release-x64
dependencies.skia.linux-x64=m90-adbb69cd7f-2/Skia-m90-adbb69cd7f-2-linux-Release-x64
dependencies.skia.macos-x64=m90-adbb69cd7f-2/Skia-m90-adbb69cd7f-2-macos-Release-x64
dependencies.skia.macos-arm64=m90-adbb69cd7f-2/Skia-m90-adbb69cd7f-2-macos-Release-arm64

# signer=Apple Distribution: Nikolay Igotti (N462MKSJ7M)
4 changes: 2 additions & 2 deletions skiko/src/jvmMain/cpp/common/awt_jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ extern "C"
awt->FreeDrawingSurface(ds);
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_lockDrawingSurface(JNIEnv *env, jobject obj, jlong drawingSurfacePtr)
JNIEXPORT jint JNICALL Java_org_jetbrains_skiko_AWTKt_lockDrawingSurface(JNIEnv *env, jobject obj, jlong drawingSurfacePtr)
{
JAWT_DrawingSurface *ds = fromJavaPointer<JAWT_DrawingSurface *>(drawingSurfacePtr);
ds->Lock(ds);
return (ds->Lock(ds) & JAWT_LOCK_ERROR) != 0;
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_unlockDrawingSurface(JNIEnv *env, jobject obj, jlong drawingSurfacePtr)
Expand Down
4 changes: 2 additions & 2 deletions skiko/src/jvmMain/kotlin/org/jetbrains/skiko/AWT.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class DrawingSurface(
}
private set

fun lock() = lockDrawingSurface(ptr)
fun lock() = lockDrawingSurface(ptr).also { check(it == 0) }

fun unlock() = unlockDrawingSurface(ptr)

Expand Down Expand Up @@ -74,7 +74,7 @@ private external fun getAWT(): Long
private external fun getDrawingSurface(awt: Long, layer: Component): Long
private external fun freeDrawingSurface(awt: Long, drawingSurface: Long)

private external fun lockDrawingSurface(drawingSurface: Long)
private external fun lockDrawingSurface(drawingSurface: Long): Int
private external fun unlockDrawingSurface(drawingSurface: Long)

private external fun getDrawingSurfaceInfo(drawingSurface: Long): Long
Expand Down
12 changes: 12 additions & 0 deletions skiko/src/jvmMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import javax.swing.SwingUtilities
internal interface PlatformOperations {
fun isFullscreen(component: Component): Boolean
fun setFullscreen(component: Component, value: Boolean)
fun disableTitleBar(platformInfo: Long)
fun getDpiScale(component: Component): Float
fun createRedrawer(layer: SkiaLayer, renderApi: GraphicsApi, properties: SkiaLayerProperties): Redrawer
}
Expand All @@ -33,6 +34,10 @@ internal val platformOperations: PlatformOperations by lazy {
return component.graphicsConfiguration.defaultTransform.scaleX.toFloat()
}

override fun disableTitleBar(platformInfo: Long) {
osxDisableTitleBar(platformInfo)
}

override fun createRedrawer(
layer: SkiaLayer,
renderApi: GraphicsApi,
Expand All @@ -57,6 +62,9 @@ internal val platformOperations: PlatformOperations by lazy {
device.setFullScreenWindow(if (value) window else null)
}

override fun disableTitleBar(platformInfo: Long) {
}

override fun getDpiScale(component: Component): Float {
return component.graphicsConfiguration.defaultTransform.scaleX.toFloat()
}
Expand Down Expand Up @@ -86,6 +94,9 @@ internal val platformOperations: PlatformOperations by lazy {
device.setFullScreenWindow(if (value) window else null)
}

override fun disableTitleBar(platformInfo: Long) {
}

override fun getDpiScale(component: Component): Float {
return component.graphicsConfiguration.defaultTransform.scaleX.toFloat()
// TODO doesn't work well because java doesn't scale windows (content has offset with 200% scale)
Expand Down Expand Up @@ -118,6 +129,7 @@ internal val platformOperations: PlatformOperations by lazy {
// OSX
external private fun osxIsFullscreenNative(component: Component): Boolean
external private fun osxSetFullscreenNative(component: Component, value: Boolean)
external private fun osxDisableTitleBar(platformInfo: Long)

// Linux
external private fun linuxGetDpiScaleNative(platformInfo: Long): Float
6 changes: 6 additions & 0 deletions skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkiaWindow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ open class SkiaWindow(
layer.dispose()
super.dispose()
}

fun disableTitleBar() {
useDrawingSurfacePlatformInfo {
platformOperations.disableTitleBar(it)
}
}
}
59 changes: 38 additions & 21 deletions skiko/src/jvmMain/objectiveC/macos/Drawlayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,35 @@ - (void) makeFullscreen: (BOOL) value
return recursiveWindowSearch(rootView, layer);
}

NSWindow *findWindow(jlong platformInfoPtr)
{
NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) platformInfoPtr;
CALayer* ca_layer = [dsi_mac windowLayer];

NSWindow* target_window = nil;

NSMutableArray<NSWindow *> *windows = [NSMutableArray arrayWithArray: [[NSApplication sharedApplication] windows]];
for (NSWindow* window in windows)
{
target_window = findCALayerWindow(window.contentView, ca_layer);
if (target_window != nil) break;
}
return target_window;
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr)
{
if (layerStorage == nil)
{
layerStorage = [[NSMutableSet alloc] init];
}

NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) platformInfoPtr;

LayerHandler *layersSet = [[LayerHandler alloc] init];

NSObject<JAWT_SurfaceLayers>* dsi_mac = (__bridge NSObject<JAWT_SurfaceLayers> *) platformInfoPtr;
layersSet.container = [dsi_mac windowLayer];
jobject canvasGlobalRef = env->NewGlobalRef(canvas);
[layersSet setCanvasGlobalRef: canvasGlobalRef];

NSMutableArray<NSWindow *> *windows = [NSMutableArray arrayWithArray: [[NSApplication sharedApplication] windows]];
for (NSWindow* window in windows) {
layersSet.window = findCALayerWindow(window.contentView, layersSet.container);
if (layersSet.window != nil) {
break;
}
}
layersSet.window = findWindow(platformInfoPtr);

[layerStorage addObject: layersSet];
}
Expand All @@ -141,16 +148,6 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeDispose(JNIE
}
}

JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas)
{
LayerHandler *layer = findByObject(env, canvas);
if (layer != NULL)
{
return (jlong)[layer window];
}
return (jlong)kNullWindowHandle;
}

JNIEXPORT jboolean JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxIsFullscreenNative(JNIEnv *env, jobject properties, jobject component)
{
LayerHandler *layer = findByObject(env, component);
Expand All @@ -170,6 +167,26 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxSetFulls
}
}

JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas, jlong platformInfoPtr)
{
NSWindow* window = findWindow(platformInfoPtr);
return (jlong)window;
}

JNIEXPORT void JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_osxDisableTitleBar(JNIEnv *env, jobject properties, jlong platformInfoPtr)
{
NSWindow* window = findWindow(platformInfoPtr);
if (window == nil) return;
dispatch_async(dispatch_get_main_queue(), ^{
[window setTitlebarAppearsTransparent:YES];
[window setTitleVisibility:NSWindowTitleHidden];
[window setStyleMask:[window styleMask]|NSWindowStyleMaskFullSizeContentView];
// always show `fullscreen` green traffic light button instead of `maximize/zoom` button
[window setCollectionBehavior:[window collectionBehavior]|NSWindowCollectionBehaviorFullScreenPrimary];
[window setMovable:NO];
});
}

void getMetalDeviceAndQueue(void** device, void** queue)
{
id<MTLDevice> fDevice = MTLCreateSystemDefaultDevice();
Expand Down

0 comments on commit 7ea3f41

Please sign in to comment.