@@ -104,6 +104,23 @@ fn main() -> Result<(), Box<dyn Error>> {
104104 state. playlist = args. file . clone ( ) ;
105105 state. playlist_index = 0 ;
106106
107+ let mut history_changed = false ;
108+ for path in & args. file {
109+ if path. starts_with ( "http" ) {
110+ if !state. url_history . iter ( ) . any ( |( u, _) | u == path) {
111+ state. url_history . push ( ( path. clone ( ) , "Network Stream" . to_string ( ) ) ) ;
112+ history_changed = true ;
113+ }
114+ }
115+ }
116+ if history_changed {
117+ let mut out = String :: new ( ) ;
118+ for ( u, t) in & state. url_history {
119+ out. push_str ( & format ! ( "{}|{}\n " , u, t) ) ;
120+ }
121+ let _ = std:: fs:: write ( crate :: state:: get_history_file_path ( ) , out) ;
122+ }
123+
107124 if let Some ( vis) = & args. vis {
108125 let vis_lower = vis. to_lowercase ( ) ;
109126 if let Some ( idx) = crate :: state:: VISUALIZERS . iter ( ) . position ( |v| v. filename . to_lowercase ( ) . contains ( & vis_lower) || v. name . to_lowercase ( ) . contains ( & vis_lower) ) {
@@ -256,9 +273,12 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
256273 modifiers = m. state ( ) ;
257274 }
258275
259- // Process global hotkeys regardless of egui consuming them
260- if let WindowEvent :: KeyboardInput { event : kb_event, .. } = & event {
261- if kb_event. state == ElementState :: Pressed {
276+ let wants_keyboard = egui_ctx. wants_keyboard_input ( ) ;
277+
278+ // Process global hotkeys only if egui doesn't want keyboard input (e.g. typing in a text box)
279+ if !wants_keyboard {
280+ if let WindowEvent :: KeyboardInput { event : kb_event, .. } = & event {
281+ if kb_event. state == ElementState :: Pressed {
262282 if let PhysicalKey :: Code ( keycode) = kb_event. physical_key {
263283 match keycode {
264284 WinitKeyCode :: ArrowRight | WinitKeyCode :: ArrowLeft | WinitKeyCode :: Comma | WinitKeyCode :: Period => {
@@ -437,6 +457,7 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
437457 }
438458 }
439459 }
460+ }
440461 }
441462 }
442463
@@ -796,20 +817,35 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
796817 }
797818 EngineAction :: OpenUrlDialog => {
798819 state. is_url_dialog_open = true ;
820+ state. focus_url_input = true ;
821+ window. set_ime_allowed ( true ) ; // Hint to Wayland/SteamOS to show the virtual keyboard
822+ }
823+ EngineAction :: ClearFocusUrlInput => {
824+ state. focus_url_input = false ;
799825 }
800826 EngineAction :: CloseUrlDialog => {
801827 state. is_url_dialog_open = false ;
828+ window. set_ime_allowed ( false ) ;
802829 }
803830 EngineAction :: SetUrlInput ( url) => {
804831 state. url_input_text = url;
805832 }
806833 EngineAction :: LoadUrl ( url) => {
807834 state. is_url_dialog_open = false ;
835+ window. set_ime_allowed ( false ) ;
808836 state. url_input_text . clear ( ) ;
809837 state. playlist = vec ! [ url. clone( ) ] ;
810838 state. playlist_index = 0 ;
811- state. load_request = Some ( url) ;
839+ state. load_request = Some ( url. clone ( ) ) ;
812840 state. file_loaded = true ;
841+ if !state. url_history . iter ( ) . any ( |( u, _) | u == & url) {
842+ state. url_history . push ( ( url. clone ( ) , "Network Stream" . to_string ( ) ) ) ;
843+ let mut out = String :: new ( ) ;
844+ for ( u, t) in & state. url_history {
845+ out. push_str ( & format ! ( "{}|{}\n " , u, t) ) ;
846+ }
847+ let _ = std:: fs:: write ( crate :: state:: get_history_file_path ( ) , out) ;
848+ }
813849 }
814850 EngineAction :: None => { }
815851 }
@@ -880,7 +916,10 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
880916 }
881917 } ,
882918 Event :: AboutToWait => {
883- let is_dialog_open = * file_dialog. state ( ) != egui_file_dialog:: DialogState :: Closed ;
919+ let is_dialog_open = * file_dialog. state ( ) != egui_file_dialog:: DialogState :: Closed || {
920+ let state = app_state. lock ( ) . unwrap ( ) ;
921+ state. is_url_dialog_open
922+ } ;
884923
885924 {
886925 let mut state = app_state. lock ( ) . unwrap ( ) ;
@@ -973,8 +1012,41 @@ async fn run_gui(app_state: Arc<Mutex<AppState>>, mut active_stream: Option<audi
9731012 gilrs:: Button :: DPadRight => { push_key ( egui:: Key :: ArrowRight ) ; continue ; }
9741013 gilrs:: Button :: South => { push_key ( egui:: Key :: Enter ) ; continue ; }
9751014 gilrs:: Button :: East => { push_key ( egui:: Key :: Escape ) ; continue ; }
1015+ gilrs:: Button :: RightTrigger => {
1016+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : true , repeat : false , modifiers : egui:: Modifiers :: NONE } ) ;
1017+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : false , repeat : false , modifiers : egui:: Modifiers :: NONE } ) ;
1018+ continue ;
1019+ }
1020+ gilrs:: Button :: LeftTrigger => {
1021+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : true , repeat : false , modifiers : egui:: Modifiers :: SHIFT } ) ;
1022+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : false , repeat : false , modifiers : egui:: Modifiers :: SHIFT } ) ;
1023+ continue ;
1024+ }
9761025 _ => { }
9771026 }
1027+ } else {
1028+ let is_splash = {
1029+ let state = app_state. lock ( ) . unwrap ( ) ;
1030+ !state. file_loaded
1031+ } ;
1032+ if is_splash {
1033+ let mut state = app_state. lock ( ) . unwrap ( ) ;
1034+ let mut push_tab = |shift : bool | {
1035+ let modifiers = if shift { egui:: Modifiers :: SHIFT } else { egui:: Modifiers :: NONE } ;
1036+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : true , repeat : false , modifiers } ) ;
1037+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Tab , physical_key : None , pressed : false , repeat : false , modifiers } ) ;
1038+ } ;
1039+ match button {
1040+ gilrs:: Button :: DPadLeft => { push_tab ( true ) ; continue ; }
1041+ gilrs:: Button :: DPadRight => { push_tab ( false ) ; continue ; }
1042+ gilrs:: Button :: South => {
1043+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Enter , physical_key : None , pressed : true , repeat : false , modifiers : egui:: Modifiers :: NONE } ) ;
1044+ state. egui_gamepad_events . push ( egui:: Event :: Key { key : egui:: Key :: Enter , physical_key : None , pressed : false , repeat : false , modifiers : egui:: Modifiers :: NONE } ) ;
1045+ continue ;
1046+ }
1047+ _ => { }
1048+ }
1049+ }
9781050 }
9791051
9801052 match button {
0 commit comments