Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
37d2622
feat(Linux): implement Linux touch input handling and refactor captio…
GaodaGG Oct 18, 2026
1a1945b
refactor(Linux): simplify gesture handling by removing unused MouseEv…
GaodaGG Oct 18, 2026
db65b26
refactor(Linux): enhance gesture handling by applying pending resize …
GaodaGG Oct 18, 2026
b1361e5
refactor(Linux): streamline input handling by integrating LinuxWindow…
GaodaGG Oct 18, 2026
a35c01b
refactor(Linux): simplify caption bar input handling and enhance hit …
GaodaGG Oct 18, 2026
4e30c6d
refactor(Linux): enhance touch input handling by adding time tracking…
GaodaGG Oct 18, 2026
4ac48b3
fix(Linux): cancel window gestures when input detaches
GaodaGG Oct 18, 2026
58f3ed6
refactor(linux): split gesture logic and organize platform packages
GaodaGG Oct 18, 2026
16a1b71
refactor(linux): isolate gesture state and synchronize sheet tests
GaodaGG Oct 18, 2026
e3b79b5
fix(Linux): respect AWT modality for native XI2 input
GaodaGG Oct 18, 2026
b4ed816
fix(Linux): finish mouse gestures while touch contacts are held
GaodaGG Oct 18, 2026
4eabc62
fix(Linux): add JVM arguments for test tasks to open AWT packages
GaodaGG Oct 18, 2026
d643803
fix(Linux): isolate input assertions from window setup events
GaodaGG Oct 18, 2026
e44e7ee
refactor(Linux): separate XI2 polling from event dispatch
GaodaGG Oct 18, 2026
ec5594c
refactor(Linux): separate gesture ownership from phase handling
GaodaGG Oct 18, 2026
aedcab2
fix(Linux): correct bitwise operation in event handling
GaodaGG Oct 18, 2026
83a1e30
fix(Linux): correct touch handoff to the window manager
GaodaGG Oct 19, 2026
dd11731
fix(Linux): fall back to public AWT modality checks
GaodaGG Oct 19, 2026
0b8f135
refactor(Linux): remove unused Toolkit import and related comment
GaodaGG Oct 19, 2026
2ee9e7d
fix(Linux): reduce redundant resize-edge reports and input cancellations
GaodaGG Oct 19, 2026
3baa51e
refactor(Linux): replace X11Ext with LinuxX11 and clean up unused code
GaodaGG Oct 19, 2026
cd29e42
fix(Linux): correct TOUCH_BITS calculation for accurate bitwise opera…
GaodaGG Oct 19, 2026
6af4660
fix(linux): keep native dialog captions draggable
GaodaGG Oct 19, 2026
114b8aa
fix(linux): preserve caption anchors when restoring maximized windows
GaodaGG Oct 19, 2026
5b53e03
docs(linux): explain why raw button release is not filtered by device
GaodaGG Oct 20, 2026
d633dfe
test(linux): cover window gestures and layered dialog captions
GaodaGG Oct 20, 2026
29d17aa
fix(linux): release native mouse move when the XI2 session fails
GaodaGG Oct 20, 2026
62371b2
Merge remote-tracking branch 'origin/main' into feature/linux-touch-i…
GaodaGG Oct 20, 2026
bce0f2d
test(linux): make native drag tests independent of Openbox move repor…
GaodaGG Oct 20, 2026
b1a0fb0
test(linux): keep synthetic touch contacts fixed on screen
GaodaGG Oct 20, 2026
22c46c9
test(linux): wait for the WM move before a fresh caption press
GaodaGG Oct 20, 2026
d364190
refactor(test): rename LinuxInputWindow to LinuxInputWindowTest for c…
GaodaGG Oct 22, 2026
c9bc231
refactor(linux): simplify caption bar input modifier setup
GaodaGG Oct 22, 2026
8e0c569
refactor(linux): improve conditional rendering in Content function
GaodaGG Oct 23, 2026
0c37816
refactor(linux): remove unnecessary blank line in UndecoratedWindowRe…
GaodaGG Oct 23, 2026
c966018
refactor(linux): rename modalBlocked to isModalBlockedMethod for clarity
GaodaGG Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ui2/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ dependencies {
val configureAppleTargets = rootProject.extra["configureAppleTargets"] as Boolean

tasks.withType<Test>().configureEach {
if (System.getProperty("os.name").startsWith("Linux")) {
jvmArgs(
"--add-opens=java.desktop/java.awt=ALL-UNNAMED",
"--add-opens=java.desktop/sun.awt=ALL-UNNAMED",
"--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED"
)
}
testLogging {
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ import androidx.compose.ui.window.WindowDecoration
import com.moriafly.salt.ui.ChangeSaltThemeIsDark
import com.moriafly.salt.ui.SaltTheme
import com.moriafly.salt.ui.UnstableSaltUiApi
import com.moriafly.salt.ui.platform.linux.decoration.LinuxCaptionButtonClose
import com.moriafly.salt.ui.platform.linux.decoration.LinuxCaptionButtonWidth
import com.moriafly.salt.ui.platform.linux.decoration.LinuxClientShadow
import com.moriafly.salt.ui.platform.linux.decoration.LinuxClientShadowEffect
import com.moriafly.salt.ui.platform.linux.decoration.linuxClientShadow
import com.moriafly.salt.ui.platform.linux.input.LinuxWindowGestures
import com.moriafly.salt.ui.platform.linux.input.LinuxWindowInputEffect
import com.moriafly.salt.ui.platform.linux.input.LocalLinuxWindowGestures
import com.moriafly.salt.ui.platform.linux.window.LinuxCaptionBarHitTest
import com.moriafly.salt.ui.platform.linux.window.LinuxWindowGestureEffects
import com.moriafly.salt.ui.platform.linux.window.LocalLinuxCaptionBarHitTest
import com.moriafly.salt.ui.platform.linux.window.UndecoratedWindowResizer
import com.moriafly.salt.ui.thenIf
import com.moriafly.salt.ui.window.CaptionButtonsAlign
import com.moriafly.salt.ui.window.LocalIsHitTestInCaptionBarState
Expand All @@ -65,17 +77,11 @@ internal fun DialogWindowScope.LinuxSaltDialogWindowFrame(
properties: SaltWindowProperties<ComposeDialog>,
content: @Composable DialogWindowScope.() -> Unit
) {
DisposableEffect(window) {
val focus = LinuxWindowFocus.install(window)
onDispose { focus?.close() }
}

val currentProperties by rememberUpdatedState(properties)
val isHitTestInCaptionBar = remember { mutableStateOf(false) }
val captionBarHitTest = remember { LinuxCaptionBarHitTest() }
val undecoratedWindowResizer = remember {
UndecoratedWindowResizer(
window = window,
onResizeEdgeChange = { edge ->
currentProperties.onResizeEdgeChange(window, edge)
}
Expand All @@ -85,6 +91,16 @@ internal fun DialogWindowScope.LinuxSaltDialogWindowFrame(
// Dialogs are never maximized, so the shadow margin is constant
val shadowMargin = if (clientShadow) LinuxClientShadow.margin else 0.dp

val windowGestures = remember(window) {
LinuxWindowGestures(
window = window,
caption = captionBarHitTest,
resizer = undecoratedWindowResizer,
captionHovered = isHitTestInCaptionBar,
effects = LinuxWindowGestureEffects(window, undecoratedWindowResizer)
)
}

CompositionLocalProvider(
LocalSaltWindowInfo provides SaltWindowInfo(
captionBarHeight = properties.captionBarHeight,
Expand All @@ -96,16 +112,15 @@ internal fun DialogWindowScope.LinuxSaltDialogWindowFrame(
cornerRadius = if (clientShadow) LinuxClientShadow.cornerRadius else 0.dp
),
LocalLinuxCaptionBarHitTest provides captionBarHitTest,
LocalLinuxWindowGestures provides windowGestures,
LocalIsHitTestInCaptionBarState provides isHitTestInCaptionBar
) {
if (currentProperties.moveable) {
LinuxCaptionBarDragHandler(
window = window,
hitTest = captionBarHitTest,
isMoveable = properties.moveable,
isHitTestInCaptionBar = isHitTestInCaptionBar.value
)
}
LinuxWindowInputEffect(
window = window,
gestures = windowGestures,
moveable = properties.moveable,
resizable = resizable
)

LaunchedEffect(decoration) {
undecoratedWindowResizer.resizerThickness =
Expand All @@ -124,10 +139,6 @@ internal fun DialogWindowScope.LinuxSaltDialogWindowFrame(
)
}

LaunchedEffect(resizable) {
undecoratedWindowResizer.enabled = resizable
}

Box(
modifier = Modifier
.fillMaxSize()
Expand Down
Loading
Loading