mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-08-04 02:28:36 +00:00
feat: Implement native desktop window chrome support for Windows
This commit is contained in:
parent
128f7322d0
commit
0acce0d3b5
5 changed files with 90 additions and 0 deletions
|
|
@ -428,6 +428,7 @@ val windowsPlayerBridgeCommand = if (missingWindowsPlayerBridgeInputs.isNotEmpty
|
|||
"Ole32.lib",
|
||||
"User32.lib",
|
||||
"Gdi32.lib",
|
||||
"Dwmapi.lib",
|
||||
).joinToString(" ")
|
||||
val powershellCompileCommand = compileCommand.replace("\"", "__DQ__")
|
||||
val powershellCommand = """
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.nuvio.app
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
|
@ -9,6 +10,7 @@ import androidx.compose.ui.window.WindowState
|
|||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.nuvio.app.features.player.PlatformPlayerSurface
|
||||
import com.nuvio.app.features.player.desktop.applyNativeDesktopWindowChrome
|
||||
import com.nuvio.app.features.player.desktop.preloadNativePlayerBridgeAsync
|
||||
import java.awt.Color as AwtColor
|
||||
import javax.swing.JComponent
|
||||
|
|
@ -40,6 +42,9 @@ fun main() {
|
|||
window.contentPane.background = NuvioDesktopNativeBackground
|
||||
(window.contentPane as? JComponent)?.isOpaque = true
|
||||
}
|
||||
LaunchedEffect(window) {
|
||||
applyNativeDesktopWindowChrome(window)
|
||||
}
|
||||
|
||||
if (smokePlayerUrl == null) {
|
||||
App()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.nuvio.app.features.player.desktop
|
||||
|
||||
import java.awt.Window
|
||||
|
||||
private const val NuvioWindowBackgroundRgb = 0x0D0D0D
|
||||
private const val NuvioWindowTextRgb = 0xF5F7F8
|
||||
|
||||
internal fun applyNativeDesktopWindowChrome(window: Window) {
|
||||
if (DesktopHostOs.current != DesktopHostOs.WINDOWS || !window.isDisplayable) return
|
||||
|
||||
runCatching {
|
||||
val hwnd = AwtNativeViewResolver.resolveNativeViewPointer(window)
|
||||
NativePlayerBridge.applyWindowChrome(
|
||||
windowHwnd = hwnd,
|
||||
darkMode = true,
|
||||
captionColorRgb = NuvioWindowBackgroundRgb,
|
||||
borderColorRgb = NuvioWindowBackgroundRgb,
|
||||
textColorRgb = NuvioWindowTextRgb,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,14 @@ internal object NativePlayerBridge {
|
|||
external fun addSubtitleUrl(handle: Long, url: String)
|
||||
external fun clearExternalSubtitles(handle: Long)
|
||||
external fun clearExternalSubtitlesAndSelect(handle: Long, trackId: Int)
|
||||
external fun applyWindowChrome(
|
||||
windowHwnd: Long,
|
||||
darkMode: Boolean,
|
||||
captionColorRgb: Int,
|
||||
borderColorRgb: Int,
|
||||
textColorRgb: Int,
|
||||
)
|
||||
|
||||
external fun setSubtitleDelayMs(handle: Long, delayMs: Int)
|
||||
external fun applySubtitleStyle(
|
||||
handle: Long,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <wrl.h>
|
||||
#include <WebView2.h>
|
||||
#include <jni.h>
|
||||
|
|
@ -59,6 +60,11 @@ constexpr UINT WM_NUVIO_TASK = WM_APP + 0x4E50;
|
|||
constexpr UINT_PTR NUVIO_TIMER_ID = 0x4E50;
|
||||
const wchar_t *kMessageWindowClass = L"NuvioPlayerBridgeMessageWindow";
|
||||
const wchar_t *kContainerWindowClass = L"NuvioPlayerBridgeContainerWindow";
|
||||
constexpr DWORD kDwmwaUseImmersiveDarkMode = 20;
|
||||
constexpr DWORD kDwmwaUseImmersiveDarkModeLegacy = 19;
|
||||
constexpr DWORD kDwmwaBorderColor = 34;
|
||||
constexpr DWORD kDwmwaCaptionColor = 35;
|
||||
constexpr DWORD kDwmwaTextColor = 36;
|
||||
|
||||
std::wstring toWide(const std::string &value) {
|
||||
if (value.empty()) return std::wstring();
|
||||
|
|
@ -131,6 +137,36 @@ std::string lowerCopy(std::string value) {
|
|||
return value;
|
||||
}
|
||||
|
||||
COLORREF rgbIntToColorRef(jint rgb) {
|
||||
BYTE red = (BYTE)((rgb >> 16) & 0xFF);
|
||||
BYTE green = (BYTE)((rgb >> 8) & 0xFF);
|
||||
BYTE blue = (BYTE)(rgb & 0xFF);
|
||||
return RGB(red, green, blue);
|
||||
}
|
||||
|
||||
void setDwmWindowAttribute(HWND hwnd, DWORD attribute, const void *value, DWORD valueSize) {
|
||||
(void)DwmSetWindowAttribute(hwnd, attribute, value, valueSize);
|
||||
}
|
||||
|
||||
void applyDwmWindowChrome(HWND hwnd, bool darkMode, COLORREF captionColor, COLORREF borderColor, COLORREF textColor) {
|
||||
if (!hwnd || !IsWindow(hwnd)) return;
|
||||
|
||||
BOOL enabled = darkMode ? TRUE : FALSE;
|
||||
HRESULT darkModeResult = DwmSetWindowAttribute(
|
||||
hwnd,
|
||||
kDwmwaUseImmersiveDarkMode,
|
||||
&enabled,
|
||||
sizeof(enabled)
|
||||
);
|
||||
if (FAILED(darkModeResult)) {
|
||||
setDwmWindowAttribute(hwnd, kDwmwaUseImmersiveDarkModeLegacy, &enabled, sizeof(enabled));
|
||||
}
|
||||
|
||||
setDwmWindowAttribute(hwnd, kDwmwaCaptionColor, &captionColor, sizeof(captionColor));
|
||||
setDwmWindowAttribute(hwnd, kDwmwaBorderColor, &borderColor, sizeof(borderColor));
|
||||
setDwmWindowAttribute(hwnd, kDwmwaTextColor, &textColor, sizeof(textColor));
|
||||
}
|
||||
|
||||
bool containsCaseInsensitive(const std::string &haystack, const std::string &needle) {
|
||||
return lowerCopy(haystack).find(lowerCopy(needle)) != std::string::npos;
|
||||
}
|
||||
|
|
@ -1654,6 +1690,25 @@ Java_com_nuvio_app_features_player_desktop_NativePlayerBridge_clearExternalSubti
|
|||
if (player) player->removeExternalSubtitlesAndSelect(trackId);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_nuvio_app_features_player_desktop_NativePlayerBridge_applyWindowChrome(
|
||||
JNIEnv *,
|
||||
jobject,
|
||||
jlong windowHwnd,
|
||||
jboolean darkMode,
|
||||
jint captionColorRgb,
|
||||
jint borderColorRgb,
|
||||
jint textColorRgb
|
||||
) {
|
||||
applyDwmWindowChrome(
|
||||
(HWND)(intptr_t)windowHwnd,
|
||||
darkMode == JNI_TRUE,
|
||||
rgbIntToColorRef(captionColorRgb),
|
||||
rgbIntToColorRef(borderColorRgb),
|
||||
rgbIntToColorRef(textColorRgb)
|
||||
);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_nuvio_app_features_player_desktop_NativePlayerBridge_setSubtitleDelayMs(JNIEnv *, jobject, jlong handle, jint delayMs) {
|
||||
auto player = playerFromHandle(handle);
|
||||
|
|
|
|||
Loading…
Reference in a new issue