From 67f815d1241fcf5b1fd5ebf6e0c0b3e0486ced8c Mon Sep 17 00:00:00 2001 From: Mohamed Darwish Date: Mon, 13 Jun 2022 14:55:07 +0200 Subject: [PATCH] Rework transparent effect --- window-styler-demo/src/jvmMain/kotlin/Main.kt | 3 ++- .../compose/windowstyler/NativeUtils.kt | 1 + .../mayakapps/compose/windowstyler/Utils.kt | 7 +++++- .../compose/windowstyler/WindowBackdrop.kt | 4 +-- .../compose/windowstyler/WindowStyle.kt | 25 ++++++++++++++++--- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/window-styler-demo/src/jvmMain/kotlin/Main.kt b/window-styler-demo/src/jvmMain/kotlin/Main.kt index f9cc531..62b3fce 100644 --- a/window-styler-demo/src/jvmMain/kotlin/Main.kt +++ b/window-styler-demo/src/jvmMain/kotlin/Main.kt @@ -60,7 +60,8 @@ val backdropOptions = listOf( WindowBackdrop.Default to "Default", WindowBackdrop.Solid(Color.Red) to "Solid Red", WindowBackdrop.Solid(Color.Blue) to "Solid Blue", - WindowBackdrop.Transparent to "Transparent", + WindowBackdrop.Transparent(Color.Transparent) to "Transparent", + WindowBackdrop.Transparent(Color.Yellow.copy(alpha = 0.25F)) to "Yellow Transparent", WindowBackdrop.Aero to "Aero", WindowBackdrop.Acrylic(Color.Magenta.copy(alpha = 0.25F)) to "Acrylic Magenta", WindowBackdrop.Acrylic(Color.Cyan.copy(alpha = 0.25F)) to "Acrylic Cyan", diff --git a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/NativeUtils.kt b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/NativeUtils.kt index 5c0390c..87cd3cf 100644 --- a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/NativeUtils.kt +++ b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/NativeUtils.kt @@ -34,6 +34,7 @@ internal fun WindowBackdrop.toDwmSystemBackdrop(): DwmSystemBackdrop = internal fun WindowBackdrop.toAccentState(): AccentState = when (this) { is WindowBackdrop.Default, is WindowBackdrop.Solid -> AccentState.ACCENT_ENABLE_GRADIENT + is WindowBackdrop.Transparent -> AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT is WindowBackdrop.Aero -> AccentState.ACCENT_ENABLE_BLURBEHIND is WindowBackdrop.Acrylic -> AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND else -> AccentState.ACCENT_DISABLED diff --git a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/Utils.kt b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/Utils.kt index 176a9cb..528f98b 100644 --- a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/Utils.kt +++ b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/Utils.kt @@ -15,4 +15,9 @@ internal fun Color.toAbgr(): Int { ((color[2] * 255.0f + 0.5f).toInt() shl 16) or ((color[1] * 255.0f + 0.5f).toInt() shl 8) or (color[0] * 255.0f + 0.5f).toInt() -} \ No newline at end of file +} + +// For some reason, passing 0 (fully transparent black) to the setAccentPolicy with +// transparent accent policy results in solid red color. As a workaround, we pass +// fully transparent white which has the same visual effect. +internal fun Color.toAbgrForTransparent() = if (alpha == 0F) 0x00FFFFFF else toAbgr() \ No newline at end of file diff --git a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowBackdrop.kt b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowBackdrop.kt index c7f3c78..94cb60f 100644 --- a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowBackdrop.kt +++ b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowBackdrop.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.graphics.Color sealed interface WindowBackdrop { object Default : WindowBackdrop data class Solid(override val color: Color) : ColorableWindowBackdrop - object Transparent : WindowBackdrop + data class Transparent(override val color: Color) : ColorableWindowBackdrop object Aero : WindowBackdrop data class Acrylic(override val color: Color) : ColorableWindowBackdrop object Mica : WindowBackdrop @@ -14,4 +14,4 @@ sealed interface WindowBackdrop { internal interface ColorableWindowBackdrop : WindowBackdrop { val color: Color -} +} \ No newline at end of file diff --git a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowStyle.kt b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowStyle.kt index dfbae0b..de31c2e 100644 --- a/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowStyle.kt +++ b/window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/WindowStyle.kt @@ -29,6 +29,19 @@ fun FrameWindowScope.WindowStyle( if (windowsBuild >= 17763) { LaunchedEffect(isDarkTheme) { setImmersiveDarkModeEnabled(hwnd, isDarkTheme) + + // For some reason, using setImmersiveDarkModeEnabled after setting accent policy to transparent + // results in solid red backdrop. So, we have to reset the transparent backdrop after using it. + val finalLastEffect = lastEffect + if (finalLastEffect is WindowBackdrop.Transparent) { + setAccentPolicy(hwnd, AccentState.ACCENT_DISABLED) + setAccentPolicy( + hwnd = hwnd, + accentState = backdropType.toAccentState(), + accentFlags = setOf(AccentFlag.DRAW_ALL_BORDERS), + color = finalLastEffect.color.toAbgrForTransparent(), + ) + } } } @@ -43,8 +56,6 @@ fun FrameWindowScope.WindowStyle( // Set [ACCENT_DISABLED] as [ACCENT_POLICY] to apply styles properly. setAccentPolicy(hwnd, AccentState.ACCENT_DISABLED) - if (backdropType is WindowBackdrop.Transparent) return@invokeLater - // Only on later Windows 11 versions and if effect is WindowEffect.mica, // WindowEffect.acrylic or WindowEffect.tabbed, otherwise fallback to old // approach. @@ -73,11 +84,17 @@ fun FrameWindowScope.WindowStyle( setMicaEffectEnabled(hwnd, false) } + val color = when (backdropType) { + is WindowBackdrop.Transparent -> backdropType.color.toAbgrForTransparent() + is ColorableWindowBackdrop -> backdropType.color.toAbgr() + else -> 0x7FFFFFFF + } + setAccentPolicy( hwnd = hwnd, accentState = backdropType.toAccentState(), accentFlags = setOf(AccentFlag.DRAW_ALL_BORDERS), - color = (backdropType as? ColorableWindowBackdrop)?.color?.toAbgr() ?: 0x0FFFFFFF, + color = color, ) } } @@ -85,4 +102,4 @@ fun FrameWindowScope.WindowStyle( lastEffect = backdropType } } -} +} \ No newline at end of file