Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an alwaysOnTop flag to DialogWindow. #1120

Merged
merged 1 commit into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion compose/ui/ui/api/desktop/ui.api
Original file line number Diff line number Diff line change
Expand Up @@ -3898,7 +3898,8 @@ public abstract interface class androidx/compose/ui/window/DialogWindowScope : a
public final class androidx/compose/ui/window/Dialog_desktopKt {
public static final fun Dialog (Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/window/DialogState;ZLjava/lang/String;Landroidx/compose/ui/graphics/painter/Painter;ZZZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V
public static final fun Dialog (ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
public static final fun DialogWindow (Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/window/DialogState;ZLjava/lang/String;Landroidx/compose/ui/graphics/painter/Painter;ZZZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V
public static final synthetic fun DialogWindow (Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/window/DialogState;ZLjava/lang/String;Landroidx/compose/ui/graphics/painter/Painter;ZZZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V
public static final fun DialogWindow (Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/window/DialogState;ZLjava/lang/String;Landroidx/compose/ui/graphics/painter/Painter;ZZZZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V
public static final fun DialogWindow (ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import androidx.compose.ui.awt.ComposeDialog
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.scene.BaseComposeScene
import androidx.compose.ui.scene.LocalComposeScene
import androidx.compose.ui.scene.platformContext
import androidx.compose.ui.unit.DpSize
Expand Down Expand Up @@ -77,11 +76,50 @@ fun Dialog(
resizable,
enabled,
focusable,
alwaysOnTop = false,
onPreviewKeyEvent,
onKeyEvent,
content
)

@Deprecated(
level = DeprecationLevel.HIDDEN,
message = "Replaced by an overload that also takes alwaysOnTop",
)
@Composable
fun DialogWindow(
onCloseRequest: () -> Unit,
state: DialogState = rememberDialogState(),
visible: Boolean = true,
title: String = "Untitled",
icon: Painter? = null,
undecorated: Boolean = false,
transparent: Boolean = false,
resizable: Boolean = true,
enabled: Boolean = true,
focusable: Boolean = true,
onPreviewKeyEvent: ((KeyEvent) -> Boolean) = { false },
onKeyEvent: ((KeyEvent) -> Boolean) = { false },
content: @Composable DialogWindowScope.() -> Unit
) {
DialogWindow(
onCloseRequest,
state,
visible,
title,
icon,
undecorated,
transparent,
resizable,
enabled,
focusable,
alwaysOnTop = false,
onPreviewKeyEvent,
onKeyEvent,
content
)
}

/**
* Composes platform dialog in the current composition. When Dialog enters the composition,
* a new platform dialog will be created and receives the focus. When Dialog leaves the
Expand Down Expand Up @@ -129,6 +167,7 @@ fun Dialog(
* changing [state])
* @param enabled Can dialog react to input events
* @param focusable Can dialog receive focus
* @param alwaysOnTop Should the dialog always be on top of another windows and dialogs
* @param onPreviewKeyEvent This callback is invoked when the user interacts with the hardware
* keyboard. It gives ancestors of a focused component the chance to intercept a [KeyEvent].
* Return true to stop propagation of this event. If you return false, the key event will be
Expand All @@ -151,6 +190,7 @@ fun DialogWindow(
resizable: Boolean = true,
enabled: Boolean = true,
focusable: Boolean = true,
alwaysOnTop: Boolean = false,
onPreviewKeyEvent: ((KeyEvent) -> Boolean) = { false },
onKeyEvent: ((KeyEvent) -> Boolean) = { false },
content: @Composable DialogWindowScope.() -> Unit
Expand All @@ -165,6 +205,7 @@ fun DialogWindow(
val currentResizable by rememberUpdatedState(resizable)
val currentEnabled by rememberUpdatedState(enabled)
val currentFocusable by rememberUpdatedState(focusable)
val currentAlwaysOnTop by rememberUpdatedState(alwaysOnTop)
val currentOnCloseRequest by rememberUpdatedState(onCloseRequest)

val updater = remember(::ComponentUpdater)
Expand Down Expand Up @@ -243,6 +284,7 @@ fun DialogWindow(
set(currentResizable, dialog::setResizable)
set(currentEnabled, dialog::setEnabled)
set(currentFocusable, dialog::setFocusableWindowState)
set(currentAlwaysOnTop, dialog::setAlwaysOnTop)
}
if (state.size != appliedState.size) {
dialog.setSizeSafely(state.size, WindowPlacement.Floating)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -642,4 +642,28 @@ class DialogWindowTest {
assertThat(renderedText).isEqualTo("2")
}
}

@Test
fun `change alwaysOnTop`() = runApplicationTest {
var dialog: ComposeDialog? = null

var alwaysOnTop by mutableStateOf(false)

launchTestApplication {
DialogWindow(onCloseRequest = ::exitApplication, alwaysOnTop = alwaysOnTop) {
dialog = this.window
Box(Modifier.size(32.dp).background(Color.Red))
}
}

awaitIdle()
assertThat(dialog?.isAlwaysOnTop).isFalse()

alwaysOnTop = true
awaitIdle()
assertThat(dialog?.isAlwaysOnTop).isTrue()

dialog?.dispatchEvent(WindowEvent(dialog, WindowEvent.WINDOW_CLOSING))
}

}