22using System . IO ;
33using System . Runtime . InteropServices ;
44using System . Windows ;
5+ using System . Windows . Interop ;
56
67namespace ImmichFrame_Screensaver
78{
89 public partial class MainWindow : Window
910 {
10- //public static string settingsPath = @"C:\ProgramData\ImmichFrame_Screensaver\Settings.json";
11- public static string settingsPath = Path . Combine ( Path . GetTempPath ( ) , "ImmichFrame_Screensaver" ) ;
12- private const int WH_KEYBOARD_LL = 13 ;
13- private const int WH_MOUSE_LL = 14 ;
14-
15- // Declare the hook procedure delegate with the correct signature and make it public
16- public delegate IntPtr HookProc ( int nCode , IntPtr wParam , IntPtr lParam ) ;
17-
18- // Hook handles
19- private IntPtr _keyboardHookHandle = IntPtr . Zero ;
20- private IntPtr _mouseHookHandle = IntPtr . Zero ;
21-
22- // Delegate instances
23- private HookProc _keyboardProc ;
24- private HookProc _mouseProc ;
25-
26- private bool _inputDetectionEnabled = false ;
11+ private NativeOverlayWindow _nativeOverlay ;
2712 public MainWindow ( )
2813 {
2914 InitializeComponent ( ) ;
3015 Cursor = System . Windows . Input . Cursors . None ;
3116 LoadWebView ( ) ;
32- StartInputDelayAsync ( ) ;
33- _keyboardProc = new HookProc ( KeyboardHookProc ) ;
34- _mouseProc = new HookProc ( MouseHookProc ) ;
35- }
36- private async void StartInputDelayAsync ( )
37- {
38- _inputDetectionEnabled = false ; // Disable input detection initially
39- await Task . Delay ( 3000 ) ; // Delay for 2 seconds
40- _inputDetectionEnabled = true ; // Enable input detection
41- SetUpHooks ( ) ;
42- }
43- private void OpenSettings ( )
44- {
45- var settings = new Settings ( ) ;
46- settings . ShowDialog ( ) ;
17+ Loaded += async ( s , e ) =>
18+ {
19+ await Task . Delay ( 3000 ) ; // 3 second delay
20+ // Start the native overlay in a new thread so it doesn't block the UI
21+ _ = Task . Run ( ( ) =>
22+ {
23+ using ( _nativeOverlay = new NativeOverlayWindow ( ) )
24+ {
25+ _nativeOverlay . RunMessageLoop ( ) ;
26+ }
27+ } ) ;
28+ } ;
4729 }
48- //private void LoadWebView()
49- //{
50- // if (File.Exists(Path.Combine(MainWindow.settingsPath, "Settings.json")))
51- // {
52- // var strUrl = File.ReadAllText(Path.Combine(MainWindow.settingsPath, "Settings.json"));
53- // if (!string.IsNullOrWhiteSpace(strUrl))
54- // {
55- // WebView.Source = new Uri(strUrl);
56- // }
57- // else
58- // {
59- // MessageBox.Show("Please configure settings!");
60- // CloseScreensaver();
61- // }
62- // }
63- // else
64- // {
65- // WebView.Source = new Uri("https://github.com/immichFrame/ImmichFrame/raw/main/design/16x9%20frame.svg");
66- // }
67- //}
6830 private async void LoadWebView ( )
6931 {
7032 try
7133 {
72- string userDataFolder = Path . Combine ( settingsPath , "WebView2" ) ;
73-
74- // Ensure directory exists
34+ string userDataFolder = Path . Combine ( Settings . appDataFolder , "WebView2" ) ;
7535 Directory . CreateDirectory ( userDataFolder ) ;
7636
7737 var options = new CoreWebView2EnvironmentOptions ( "--allow-insecure-localhost --allow-running-insecure-content" ) ;
7838 var env = await CoreWebView2Environment . CreateAsync ( null , userDataFolder , options ) ;
7939 await WebView . EnsureCoreWebView2Async ( env ) ;
8040
81- // Determine URL
82- string url = "https://github.com/immichFrame/ImmichFrame/raw/main/design/16x9%20frame.svg" ;
41+ // Use SavedUrl if valid, else fallback to default
42+ string defaultUrl = "https://github.com/immichFrame/ImmichFrame/raw/main/design/16x9%20frame.svg" ;
43+ string url = ! string . IsNullOrWhiteSpace ( Settings . CurrentSettings . SavedUrl )
44+ ? Settings . CurrentSettings . SavedUrl
45+ : defaultUrl ;
8346
84- string settingsFile = Path . Combine ( MainWindow . settingsPath , "Settings.json" ) ;
85- if ( File . Exists ( settingsFile ) )
47+ // Validate URL
48+ if ( ! Uri . TryCreate ( url , UriKind . Absolute , out var uriResult ) )
8649 {
87- string strUrl = File . ReadAllText ( settingsFile ) ;
88- if ( ! string . IsNullOrWhiteSpace ( strUrl ) )
89- {
90- url = strUrl . Trim ( ) ;
91- }
92- else
93- {
94- MessageBox . Show ( "Please configure settings!" ) ;
95- CloseScreensaver ( ) ;
96- return ;
97- }
50+ MessageBox . Show ( "Invalid URL in settings. Using placeholder." ) ;
51+ uriResult = new Uri ( defaultUrl ) ;
9852 }
9953
100- WebView . Source = new Uri ( url ) ;
54+ WebView . Source = uriResult ;
10155 }
10256 catch ( Exception ex )
10357 {
@@ -106,55 +60,9 @@ private async void LoadWebView()
10660 }
10761 }
10862
109- private void SetUpHooks ( )
110- {
111- // Set the keyboard hook
112- _keyboardHookHandle = SetWindowsHookEx ( WH_KEYBOARD_LL , _keyboardProc , IntPtr . Zero , 0 ) ;
113- // Set the mouse hook
114- _mouseHookHandle = SetWindowsHookEx ( WH_MOUSE_LL , _mouseProc , IntPtr . Zero , 0 ) ;
115- }
116-
117- private IntPtr KeyboardHookProc ( int nCode , IntPtr wParam , IntPtr lParam )
118- {
119- if ( _inputDetectionEnabled && nCode >= 0 )
120- {
121- CloseScreensaver ( ) ;
122- }
123- return CallNextHookEx ( _keyboardHookHandle , nCode , wParam , lParam ) ;
124- }
125-
126- private IntPtr MouseHookProc ( int nCode , IntPtr wParam , IntPtr lParam )
127- {
128- if ( _inputDetectionEnabled && nCode >= 0 )
129- {
130- CloseScreensaver ( ) ;
131- }
132- return CallNextHookEx ( _mouseHookHandle , nCode , wParam , lParam ) ;
133- }
134-
135-
13663 private void CloseScreensaver ( )
13764 {
13865 Application . Current . Shutdown ( ) ;
13966 }
140- [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , CallingConvention = CallingConvention . StdCall ) ]
141- public static extern IntPtr SetWindowsHookEx ( int idHook , HookProc lpfn , IntPtr hmod , uint dwThreadId ) ;
142-
143- [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , CallingConvention = CallingConvention . StdCall ) ]
144- public static extern IntPtr CallNextHookEx ( IntPtr idHook , int nCode , IntPtr wParam , IntPtr lParam ) ;
145-
146- [ DllImport ( "user32.dll" , CharSet = CharSet . Auto , CallingConvention = CallingConvention . StdCall ) ]
147- public static extern bool UnhookWindowsHookEx ( IntPtr idHook ) ;
148-
149- [ DllImport ( "kernel32.dll" , CharSet = CharSet . Auto , CallingConvention = CallingConvention . StdCall ) ]
150- public static extern IntPtr GetModuleHandle ( string lpModuleName ) ;
151-
152- // Ensure hooks are removed when the window is closed
153- protected override void OnClosed ( EventArgs e )
154- {
155- base . OnClosed ( e ) ;
156- UnhookWindowsHookEx ( _keyboardHookHandle ) ;
157- UnhookWindowsHookEx ( _mouseHookHandle ) ;
158- }
15967 }
16068}
0 commit comments