Итак, как мне получить окно распознать строку заголовка как подвижный прямоугольник, даже если он прозрачен?
Пока это то, что я сделал, чтобы достичь этого. Код очень избыточен, но сейчас я просто бездельничаю, пытаясь доказать концепцию...
- Получить дескриптор NSWindow
// Get class NSApplication
try (Arena arena = Arena.ofConfined()) {
long nsApplication = (long) objc_getClass.invoke(arena.allocateFrom("NSApplication"));
System.out.println("nsApplication: " + Long.toHexString(nsApplication));
// Get selector for sharedApplication
long sharedAppSelector = (long) sel_registerName.invoke(arena.allocateFrom("sharedApplication"));
System.out.println("sharedAppSelector: " + Long.toHexString(sharedAppSelector));
// Get NSApplication shared instance
long sharedApplication = (long) LINKER.downcallHandle(
symbolLookup.find("objc_msgSend").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG))
.invoke(nsApplication, sharedAppSelector);
System.out.println("sharedApplication: " + Long.toHexString(sharedApplication));
// Get selector for windows array
long windowsSelector = (long) sel_registerName.invoke(arena.allocateFrom("windows"));
System.out.println("windowsSelector: " + Long.toHexString(windowsSelector));
// Get array of windows (NSArray of NSWindow objects)
long windowsArray = (long) LINKER.downcallHandle(
symbolLookup.find("objc_msgSend").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG))
.invoke(sharedApplication, windowsSelector);
System.out.println("windowsArray: " + Long.toHexString(windowsArray));
// Get selector for objectAtIndex:
long objectAtIndexSelector = (long) sel_registerName.invoke(arena.allocateFrom("objectAtIndex:"));
System.out.println("objectAtIndexSelector: " + Long.toHexString(objectAtIndexSelector));
// Get first window (NSWindow) in the array (index 0)
long nsWindow = (long) LINKER.downcallHandle(
symbolLookup.find("objc_msgSend").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG))
.invoke(windowsArray, objectAtIndexSelector, (long) 0);
System.out.println("nsWindow: " + Long.toHexString(nsWindow));
return nsWindow;
}
}
- Измените NSWindow на желаемый стиль
try (Arena arena = Arena.ofConfined()) {
// TRANSPARENT TITLE BAR
var titleBarTransparentSelector = (long) sel_registerName.invoke(arena.allocateFrom("setTitlebarAppearsTransparent:"));
LINKER.downcallHandle(
symbolLookup.find("objc_msgSend").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_BOOLEAN))
.invoke(nsWindow, titleBarTransparentSelector, true);
// UPDATE STYLE MASK
long styleMaskSelector = (long) sel_registerName.invoke(arena.allocateFrom("styleMask"));
long setStyleMaskSelector = (long) sel_registerName.invoke(arena.allocateFrom("setStyleMask:"));
long styleMask = (long) LINKER.downcallHandle(
symbolLookup.find("objc_msgSend").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG))
.invoke(nsWindow, styleMaskSelector);
styleMask &= ~NSWindowStyleMaskUnifiedTitleAndToolbar;
styleMask |= NSWindowStyleMaskFullSizeContentView;
styleMask |= NSWindowStyleMaskTitled;
LINKER.downcallHandle(symbolLookup.find("objc_msgSend")
.orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG))
.invoke(nsWindow, setStyleMaskSelector, styleMask);
// TITLE SEPARATOR
int titleSeparator = 1;
long setTitlebarSeparator = (long) sel_registerName.invoke(arena.allocateFrom("setTitlebarSeparatorStyle:"));
LINKER.downcallHandle(symbolLookup.find("objc_msgSend")
.orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT))
.invoke(nsWindow, setTitlebarSeparator, titleSeparator);
// TITLE VISIBILITY (0 = visible, 1 = hidden)
int titleVisible = 0;
long setTitleVisibility = (long) sel_registerName.invoke(arena.allocateFrom("setTitleVisibility:"));
LINKER.downcallHandle(symbolLookup.find("objc_msgSend")
.orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_INT))
.invoke(nsWindow, setTitleVisibility, titleVisible);
// MOVABLE
var setMovableSelector = (long) sel_registerName.invoke(arena.allocateFrom("setMovable:"));
LINKER.downcallHandle(symbolLookup.find("objc_msgSend")
.orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_BOOLEAN))
.invoke(nsWindow, setMovableSelector, true);
// MOVABLE BY BACKGROUND
var isMovableByBackgroundSelector = (long) sel_registerName.invoke(arena.allocateFrom("setMovableByWindowBackground:"));
LINKER.downcallHandle(symbolLookup.find("objc_msgSend")
.orElseThrow(), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_LONG, ValueLayout.JAVA_BOOLEAN))
.invoke(nsWindow, isMovableByBackgroundSelector, true);
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... t-titlebar
Мобильная версия