11import { useKeyboard , useRenderer , useTerminalDimensions } from "@opentui/solid"
22import { batch , createContext , Show , useContext , type JSX , type ParentProps } from "solid-js"
33import { useTheme } from "@tui/context/theme"
4- import { Renderable , RGBA } from "@opentui/core"
4+ import { MouseButton , Renderable , RGBA } from "@opentui/core"
55import { createStore } from "solid-js/store"
6- import { Clipboard } from "@tui/util/clipboard"
76import { useToast } from "./toast"
7+ import { Flag } from "@/flag/flag"
8+ import { Selection } from "@tui/util/selection"
89
910export function Dialog (
1011 props : ParentProps < {
@@ -16,10 +17,18 @@ export function Dialog(
1617 const { theme } = useTheme ( )
1718 const renderer = useRenderer ( )
1819
20+ let dismiss = false
21+
1922 return (
2023 < box
21- onMouseUp = { async ( ) => {
22- if ( renderer . getSelection ( ) ) return
24+ onMouseDown = { ( ) => {
25+ dismiss = ! ! renderer . getSelection ( )
26+ } }
27+ onMouseUp = { ( ) => {
28+ if ( dismiss ) {
29+ dismiss = false
30+ return
31+ }
2332 props . onClose ?.( )
2433 } }
2534 width = { dimensions ( ) . width }
@@ -32,8 +41,8 @@ export function Dialog(
3241 backgroundColor = { RGBA . fromInts ( 0 , 0 , 0 , 150 ) }
3342 >
3443 < box
35- onMouseUp = { async ( e ) => {
36- if ( renderer . getSelection ( ) ) return
44+ onMouseUp = { ( e ) => {
45+ dismiss = false
3746 e . stopPropagation ( )
3847 } }
3948 width = { props . size === "large" ? 80 : 60 }
@@ -56,8 +65,13 @@ function init() {
5665 size : "medium" as "medium" | "large" ,
5766 } )
5867
68+ const renderer = useRenderer ( )
69+
5970 useKeyboard ( ( evt ) => {
60- if ( ( evt . name === "escape" || ( evt . ctrl && evt . name === "c" ) ) && store . stack . length > 0 ) {
71+ if ( store . stack . length === 0 ) return
72+ if ( evt . defaultPrevented ) return
73+ if ( ( evt . name === "escape" || ( evt . ctrl && evt . name === "c" ) ) && renderer . getSelection ( ) ) return
74+ if ( evt . name === "escape" || ( evt . ctrl && evt . name === "c" ) ) {
6175 const current = store . stack . at ( - 1 ) !
6276 current . onClose ?.( )
6377 setStore ( "stack" , store . stack . slice ( 0 , - 1 ) )
@@ -67,7 +81,6 @@ function init() {
6781 }
6882 } )
6983
70- const renderer = useRenderer ( )
7184 let focus : Renderable | null
7285 function refocus ( ) {
7386 setTimeout ( ( ) => {
@@ -138,15 +151,17 @@ export function DialogProvider(props: ParentProps) {
138151 { props . children }
139152 < box
140153 position = "absolute"
141- onMouseUp = { async ( ) => {
142- const text = renderer . getSelection ( ) ?. getSelectedText ( )
143- if ( text && text . length > 0 ) {
144- await Clipboard . copy ( text )
145- . then ( ( ) => toast . show ( { message : "Copied to clipboard" , variant : "info" } ) )
146- . catch ( toast . error )
147- renderer . clearSelection ( )
148- }
154+ onMouseDown = { ( evt ) => {
155+ if ( ! Flag . OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT ) return
156+ if ( evt . button !== MouseButton . RIGHT ) return
157+
158+ if ( ! Selection . copy ( renderer , toast ) ) return
159+ evt . preventDefault ( )
160+ evt . stopPropagation ( )
149161 } }
162+ onMouseUp = {
163+ ! Flag . OPENCODE_EXPERIMENTAL_DISABLE_COPY_ON_SELECT ? ( ) => Selection . copy ( renderer , toast ) : undefined
164+ }
150165 >
151166 < Show when = { value . stack . length } >
152167 < Dialog onClose = { ( ) => value . clear ( ) } size = { value . size } >
0 commit comments