Skip to content

Commit cd2bdc4

Browse files
fix: Fix and simplify backdrop logic to a usable state (#44)
1 parent 2077b91 commit cd2bdc4

File tree

5 files changed

+153
-174
lines changed

5 files changed

+153
-174
lines changed

window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/TransparencyUtils.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ private fun <T : JComponent> findComponent(
6262
}.map { klass.cast(it) }.firstOrNull()
6363
}
6464

65-
private inline fun <reified T : JComponent> Container.findComponent() = findComponent(this, T::class.java)
65+
private inline fun <reified T : JComponent> Container.findComponent() =
66+
findComponent(this, T::class.java)
6667

67-
fun ComposeWindow.findSkiaLayer(): SkiaLayer? = findComponent<SkiaLayer>()
68+
private fun ComposeWindow.findSkiaLayer(): SkiaLayer? = findComponent<SkiaLayer>()
6869

6970
internal val Window.isTransparent
7071
get() = when (this) {

window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/windows/Utils.kt

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@
1717
package com.mayakapps.compose.windowstyler.windows
1818

1919
import androidx.compose.ui.awt.ComposeWindow
20-
import com.mayakapps.compose.windowstyler.WindowBackdrop
2120
import com.mayakapps.compose.windowstyler.WindowCornerPreference
2221
import com.mayakapps.compose.windowstyler.windows.jna.Nt
23-
import com.mayakapps.compose.windowstyler.windows.jna.enums.AccentState
24-
import com.mayakapps.compose.windowstyler.windows.jna.enums.DwmSystemBackdrop
2522
import com.mayakapps.compose.windowstyler.windows.jna.enums.DwmWindowCornerPreference
2623
import com.sun.jna.Native
2724
import com.sun.jna.Pointer
@@ -40,27 +37,10 @@ internal val windowsBuild by lazy {
4037
buildNumber
4138
}
4239

43-
internal fun WindowBackdrop.toDwmSystemBackdrop(): DwmSystemBackdrop =
44-
when (this) {
45-
is WindowBackdrop.Mica -> DwmSystemBackdrop.DWMSBT_MAINWINDOW
46-
is WindowBackdrop.Acrylic -> DwmSystemBackdrop.DWMSBT_TRANSIENTWINDOW
47-
is WindowBackdrop.Tabbed -> DwmSystemBackdrop.DWMSBT_TABBEDWINDOW
48-
else -> DwmSystemBackdrop.DWMSBT_DISABLE
49-
}
50-
51-
internal fun WindowBackdrop.toAccentState(): AccentState =
52-
when (this) {
53-
is WindowBackdrop.Default, is WindowBackdrop.Solid -> AccentState.ACCENT_ENABLE_GRADIENT
54-
is WindowBackdrop.Transparent -> AccentState.ACCENT_ENABLE_TRANSPARENTGRADIENT
55-
is WindowBackdrop.Aero -> AccentState.ACCENT_ENABLE_BLURBEHIND
56-
is WindowBackdrop.Acrylic -> AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND
57-
else -> AccentState.ACCENT_DISABLED
58-
}
59-
6040
internal fun WindowCornerPreference.toDwmWindowCornerPreference(): DwmWindowCornerPreference =
6141
when (this) {
6242
WindowCornerPreference.DEFAULT -> DwmWindowCornerPreference.DWMWCP_DEFAULT
6343
WindowCornerPreference.NOT_ROUNDED -> DwmWindowCornerPreference.DWMWCP_DONOTROUND
6444
WindowCornerPreference.ROUNDED -> DwmWindowCornerPreference.DWMWCP_ROUND
6545
WindowCornerPreference.SMALL_ROUNDED -> DwmWindowCornerPreference.DWMWCP_ROUNDSMALL
66-
}
46+
}

window-styler/src/jvmMain/kotlin/com/mayakapps/compose/windowstyler/windows/WindowsBackdropApis.kt

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -25,68 +25,56 @@ import com.mayakapps.compose.windowstyler.windows.jna.enums.DwmWindowAttribute
2525
import com.sun.jna.platform.win32.WinDef
2626

2727
internal class WindowsBackdropApis(private val hwnd: WinDef.HWND) {
28-
private var isSystemBackdropSet = false
29-
private var isMicaEnabled = false
30-
private var isAccentPolicySet = false
31-
private var isSheetOfGlassApplied = false
3228

33-
fun setSystemBackdrop(systemBackdrop: DwmSystemBackdrop) {
34-
createSheetOfGlassEffect()
35-
if (Dwm.setSystemBackdrop(hwnd, systemBackdrop)) {
36-
isSystemBackdropSet = systemBackdrop == DwmSystemBackdrop.DWMSBT_DISABLE
37-
if (isSystemBackdropSet) resetAccentPolicy()
29+
var systemBackdrop: DwmSystemBackdrop? = null
30+
set(value) {
31+
requireNotNull(value)
32+
if (field == value) return
33+
34+
val result = Dwm.setSystemBackdrop(hwnd, value)
35+
if (result) field = value
3836
}
39-
}
4037

41-
fun setMicaEffectEnabled(enabled: Boolean) {
42-
createSheetOfGlassEffect()
43-
if (Dwm.setWindowAttribute(hwnd, DwmWindowAttribute.DWMWA_MICA_EFFECT, enabled)) {
44-
isMicaEnabled = enabled
45-
if (isMicaEnabled) resetAccentPolicy()
38+
var isMicaEffectEnabled: Boolean? = null
39+
set(value) {
40+
requireNotNull(value)
41+
if (field == value) return
42+
43+
val result = Dwm.setWindowAttribute(hwnd, DwmWindowAttribute.DWMWA_MICA_EFFECT, value)
44+
if (result) field = value
45+
}
46+
47+
var isSheetOfGlassEffectEnabled: Boolean? = null
48+
set(value) {
49+
requireNotNull(value)
50+
51+
val result = if (value) {
52+
// Negative margins have special meaning to DwmExtendFrameIntoClientArea.
53+
// Negative margins create the "sheet of glass" effect, where the client area is
54+
// rendered as a solid surface with no window border.
55+
Dwm.extendFrameIntoClientArea(hwnd = hwnd, margin = -1)
56+
} else {
57+
// At least one margin should be non-negative in order to show the DWM window shadow
58+
// created by handling [WM_NCCALCSIZE]. Matching value with bitsdojo_window:
59+
// https://github.com/bitsdojo/bitsdojo_window/blob/adad0cd40be3d3e12df11d864f18a96a2d0fb4fb/bitsdojo_window_windows/windows/bitsdojo_window.cpp#L149
60+
Dwm.extendFrameIntoClientArea(
61+
hwnd = hwnd,
62+
leftWidth = 0,
63+
rightWidth = 0,
64+
topHeight = 1,
65+
bottomHeight = 0,
66+
)
67+
}
68+
69+
if (result) field = value
4670
}
47-
}
4871

4972
fun setAccentPolicy(
5073
accentState: AccentState = AccentState.ACCENT_DISABLED,
5174
accentFlags: Set<AccentFlag> = emptySet(),
5275
color: Int = 0,
5376
animationId: Int = 0,
5477
) {
55-
if (User32.setAccentPolicy(hwnd, accentState, accentFlags, color, animationId)) {
56-
isAccentPolicySet = accentState != AccentState.ACCENT_DISABLED
57-
if (isAccentPolicySet) {
58-
resetSystemBackdrop()
59-
resetMicaEffectEnabled()
60-
resetWindowFrame()
61-
}
62-
}
63-
}
64-
65-
fun createSheetOfGlassEffect() {
66-
if (!isSheetOfGlassApplied && Dwm.extendFrameIntoClientArea(hwnd, -1)) isSheetOfGlassApplied = true
67-
}
68-
69-
70-
fun resetSystemBackdrop() {
71-
if (isSystemBackdropSet) setSystemBackdrop(DwmSystemBackdrop.DWMSBT_DISABLE)
72-
}
73-
74-
fun resetMicaEffectEnabled() {
75-
if (isMicaEnabled) setMicaEffectEnabled(false)
76-
}
77-
78-
fun resetAccentPolicy() {
79-
if (isAccentPolicySet) setAccentPolicy(AccentState.ACCENT_DISABLED)
80-
}
81-
82-
fun resetWindowFrame() {
83-
// At least one margin should be non-negative in order to show the DWM
84-
// window shadow created by handling [WM_NCCALCSIZE].
85-
//
86-
// Matching value with bitsdojo_window.
87-
// https://github.com/bitsdojo/bitsdojo_window/blob/adad0cd40be3d3e12df11d864f18a96a2d0fb4fb/bitsdojo_window_windows/windows/bitsdojo_window.cpp#L149
88-
if (isSheetOfGlassApplied && Dwm.extendFrameIntoClientArea(hwnd, 0, 0, 1, 0)) {
89-
isSheetOfGlassApplied = false
90-
}
78+
User32.setAccentPolicy(hwnd, accentState, accentFlags, color, animationId)
9179
}
92-
}
80+
}

0 commit comments

Comments
 (0)