diff --git a/Home Assistant Taskbar Menu.sln b/Home Assistant Taskbar Menu.sln
index 8d4b325..d8de845 100644
--- a/Home Assistant Taskbar Menu.sln
+++ b/Home Assistant Taskbar Menu.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28307.1169
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32519.111
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Home Assistant Taskbar Menu", "Home Assistant Taskbar Menu\Home Assistant Taskbar Menu.csproj", "{B49305F6-8A11-43D6-AD36-864C95D4F015}"
EndProject
diff --git a/Home Assistant Taskbar Menu/App.config b/Home Assistant Taskbar Menu/App.config
index 0290434..d0fade3 100644
--- a/Home Assistant Taskbar Menu/App.config
+++ b/Home Assistant Taskbar Menu/App.config
@@ -1,19 +1,18 @@
-
-
+
-
+
-
-
+
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/Home Assistant Taskbar Menu/App.xaml.cs b/Home Assistant Taskbar Menu/App.xaml.cs
index 9683116..a1ccbce 100644
--- a/Home Assistant Taskbar Menu/App.xaml.cs
+++ b/Home Assistant Taskbar Menu/App.xaml.cs
@@ -35,13 +35,6 @@ private void OnStartup(object sender, StartupEventArgs e)
private static void StartUi(ViewConfiguration viewConfiguration, Configuration configuration)
{
- var paletteHelper = new PaletteHelper();
- var theme = paletteHelper.GetTheme();
- theme.SetBaseTheme(viewConfiguration.GetProperty(ViewConfiguration.ThemeKey) == ViewConfiguration.LightTheme
- ? new MaterialDesignLightTheme()
- : (IBaseTheme) new MaterialDesignDarkTheme());
- paletteHelper.SetTheme(theme);
-
if (configuration == null)
{
ConsoleWriter.WriteLine("NO CONFIGURATION", ConsoleColor.Red);
@@ -52,6 +45,35 @@ private static void StartUi(ViewConfiguration viewConfiguration, Configuration c
ConsoleWriter.WriteLine($"configuration.Url = {configuration.Url}", ConsoleColor.Green);
new MainWindow(configuration, viewConfiguration).Show();
}
+
+ ReloadTheme(viewConfiguration);
+ }
+
+ internal static void ReloadTheme(ViewConfiguration viewConfiguration)
+ {
+ var paletteHelper = new PaletteHelper();
+ var theme = paletteHelper.GetTheme();
+
+ ViewConfiguration.Themes currentTheme;
+ Enum.TryParse(viewConfiguration.GetProperty(ViewConfiguration.ThemeKey), true, out currentTheme);
+
+ switch (currentTheme)
+ {
+ case ViewConfiguration.Themes.Dark:
+ theme.SetBaseTheme(new MaterialDesignDarkTheme());
+ break;
+ case ViewConfiguration.Themes.Auto:
+ var systemTheme = Theme.GetSystemTheme();
+ if (systemTheme != null)
+ theme.SetBaseTheme(systemTheme.Value.GetBaseTheme());
+ break;
+ case ViewConfiguration.Themes.Light:
+ default:
+ theme.SetBaseTheme(new MaterialDesignLightTheme());
+ break;
+ }
+
+ paletteHelper.SetTheme(theme);
}
private static void CallService(Configuration configuration, string service, string data)
diff --git a/Home Assistant Taskbar Menu/Home Assistant Taskbar Menu.csproj b/Home Assistant Taskbar Menu/Home Assistant Taskbar Menu.csproj
index 9ac2256..0773685 100644
--- a/Home Assistant Taskbar Menu/Home Assistant Taskbar Menu.csproj
+++ b/Home Assistant Taskbar Menu/Home Assistant Taskbar Menu.csproj
@@ -1,9 +1,5 @@
-
-
-
-
Debug
@@ -12,7 +8,7 @@
WinExe
Home_Assistant_Taskbar_Menu
Home Assistant Taskbar Menu
- v4.6.1
+ v4.8
512
{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
4
@@ -21,6 +17,7 @@
false
+
publish\
true
Disk
@@ -50,6 +47,7 @@
DEBUG;TRACE
prompt
4
+ true
AnyCPU
@@ -81,11 +79,12 @@
- true
+ false
x64
true
+ bin\x64\Release\
true
@@ -113,37 +112,15 @@
true
+
+ x64
+ TRACE;DEBUG
+ bin\x64\Debug\
+
-
- ..\packages\Hardcodet.NotifyIcon.Wpf.1.0.8\lib\net451\Hardcodet.Wpf.TaskbarNotification.dll
-
-
- ..\packages\MaterialDesignColors.1.2.6\lib\net45\MaterialDesignColors.dll
-
-
- ..\packages\MaterialDesignThemes.3.1.3\lib\net45\MaterialDesignThemes.Wpf.dll
-
-
- ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
-
-
- ..\packages\System.Reactive.4.3.2\lib\net46\System.Reactive.dll
-
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
-
-
- ..\packages\System.Threading.Channels.4.7.0\lib\netstandard2.0\System.Threading.Channels.dll
-
-
- ..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll
-
-
- ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll
-
@@ -158,9 +135,6 @@
4.0
-
- ..\packages\Websocket.Client.4.3.15\lib\netstandard2.0\Websocket.Client.dll
-
@@ -276,9 +250,6 @@
Resources.Designer.cs
-
- Designer
-
SettingsSingleFileGenerator
@@ -303,20 +274,22 @@
false
+
+
+ 102.0.90
+
+
+ 1.1.0
+
+
+ 4.5.0
+
+
+ 13.0.1
+
+
+ 4.4.43
+
+
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Home Assistant Taskbar Menu/Properties/Resources.Designer.cs b/Home Assistant Taskbar Menu/Properties/Resources.Designer.cs
index 25312e2..66b6b06 100644
--- a/Home Assistant Taskbar Menu/Properties/Resources.Designer.cs
+++ b/Home Assistant Taskbar Menu/Properties/Resources.Designer.cs
@@ -8,18 +8,10 @@
//
//------------------------------------------------------------------------------
-using System.CodeDom.Compiler;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Resources;
-using System.Runtime.CompilerServices;
-
-namespace Home_Assistant_Taskbar_Menu.Properties
-{
-
-
+namespace Home_Assistant_Taskbar_Menu.Properties {
+ using System;
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -27,51 +19,43 @@ namespace Home_Assistant_Taskbar_Menu.Properties
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [DebuggerNonUserCode()]
- [CompilerGenerated()]
- internal class Resources
- {
-
- private static ResourceManager resourceMan;
-
- private static CultureInfo resourceCulture;
-
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources()
- {
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- internal static ResourceManager ResourceManager
- {
- get
- {
- if ((resourceMan == null))
- {
- ResourceManager temp = new ResourceManager("Home_Assistant_Taskbar_Menu.Properties.Resources", typeof(Resources).Assembly);
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Home_Assistant_Taskbar_Menu.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
///
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- internal static CultureInfo Culture
- {
- get
- {
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
return resourceCulture;
}
- set
- {
+ set {
resourceCulture = value;
}
}
diff --git a/Home Assistant Taskbar Menu/Properties/Settings.Designer.cs b/Home Assistant Taskbar Menu/Properties/Settings.Designer.cs
index 6ccc6fa..90a6c47 100644
--- a/Home Assistant Taskbar Menu/Properties/Settings.Designer.cs
+++ b/Home Assistant Taskbar Menu/Properties/Settings.Designer.cs
@@ -8,25 +8,17 @@
//
//------------------------------------------------------------------------------
-using System.CodeDom.Compiler;
-using System.Configuration;
-using System.Runtime.CompilerServices;
-
-namespace Home_Assistant_Taskbar_Menu.Properties
-{
-
-
- [CompilerGenerated()]
- [GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
- internal sealed partial class Settings : ApplicationSettingsBase
- {
-
- private static Settings defaultInstance = ((Settings)(Synchronized(new Settings())));
-
- public static Settings Default
- {
- get
- {
+namespace Home_Assistant_Taskbar_Menu.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
return defaultInstance;
}
}
diff --git a/Home Assistant Taskbar Menu/Utils/ViewConfiguration.cs b/Home Assistant Taskbar Menu/Utils/ViewConfiguration.cs
index 010aec8..ddb5434 100644
--- a/Home Assistant Taskbar Menu/Utils/ViewConfiguration.cs
+++ b/Home Assistant Taskbar Menu/Utils/ViewConfiguration.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Home_Assistant_Taskbar_Menu.Entities;
@@ -7,8 +8,12 @@ namespace Home_Assistant_Taskbar_Menu.Utils
public class ViewConfiguration
{
public const string ThemeKey = "Theme";
- public const string LightTheme = "Light";
- public const string DarkTheme = "Dark";
+ public enum Themes
+ {
+ Auto,
+ Light,
+ Dark
+ }
public const string MirrorNotificationsKey = "MirrorNotifications";
public Type NodeType { get; set; }
@@ -41,7 +46,7 @@ public static ViewConfiguration Default()
Children = new List(),
Properties = new Dictionary
{
- {ThemeKey, LightTheme},
+ {ThemeKey, Enum.GetName(typeof(ViewConfiguration.Themes), ViewConfiguration.Themes.Auto)},
{MirrorNotificationsKey, true.ToString()}
}
};
diff --git a/Home Assistant Taskbar Menu/Views/BrowserWindow.xaml b/Home Assistant Taskbar Menu/Views/BrowserWindow.xaml
index 2a3cf1c..055a9a8 100644
--- a/Home Assistant Taskbar Menu/Views/BrowserWindow.xaml
+++ b/Home Assistant Taskbar Menu/Views/BrowserWindow.xaml
@@ -16,6 +16,7 @@
ResizeMode="CanResize"
WindowStyle="SingleBorderWindow"
Closed="BrowserWindow_OnClosed"
+ Activated="Window_Activated"
WindowStartupLocation="Manual">
public partial class BrowserWindow : Window
{
+
+ private IntPtr _windowHandle;
+ protected override void OnSourceInitialized(EventArgs e)
+ {
+ base.OnSourceInitialized(e);
+ _windowHandle = new WindowInteropHelper(this).Handle;
+ }
+ [DllImport("user32.dll")]
+ static extern IntPtr GetForegroundWindow();
+ private System.Timers.Timer focusLossTimer = new System.Timers.Timer();
+
+
private string Url { get; }
public BrowserWindow(Configuration configuration)
@@ -35,6 +50,18 @@ public BrowserWindow(Configuration configuration)
Width = position.Value.width;
Height = position.Value.height;
}
+
+
+ focusLossTimer.Elapsed += (s, e) => {
+ if(GetForegroundWindow() != _windowHandle && Visibility == Visibility.Visible)
+ {
+ Debug.WriteLine("Hiding browser window due to focus loss");
+ Application.Current.Dispatcher.Invoke(new Action(() => { Hide(); }));
+ }
+ };
+ focusLossTimer.Interval = 500;
+ focusLossTimer.Enabled = true;
+
}
private void MinimizeButton(object sender, RoutedEventArgs e)
@@ -50,6 +77,7 @@ private void MaximizeRestoreButton(object sender, RoutedEventArgs e)
private void CloseButton(object sender, RoutedEventArgs e)
{
Hide();
+ focusLossTimer.Stop();
}
private void HeaderMouseDown(object sender, MouseButtonEventArgs e)
@@ -72,5 +100,10 @@ private void BrowserWindow_OnClosed(object sender, EventArgs e)
{
Storage.SavePosition((Left, Top, Width, Height));
}
+
+ private void Window_Activated(object sender, EventArgs e)
+ {
+ focusLossTimer.Start();
+ }
}
}
\ No newline at end of file
diff --git a/Home Assistant Taskbar Menu/Views/MainWindow.xaml b/Home Assistant Taskbar Menu/Views/MainWindow.xaml
index e52dd61..6b0e655 100644
--- a/Home Assistant Taskbar Menu/Views/MainWindow.xaml
+++ b/Home Assistant Taskbar Menu/Views/MainWindow.xaml
@@ -15,8 +15,8 @@
diff --git a/Home Assistant Taskbar Menu/Views/MainWindow.xaml.cs b/Home Assistant Taskbar Menu/Views/MainWindow.xaml.cs
index 67d281f..d6510eb 100644
--- a/Home Assistant Taskbar Menu/Views/MainWindow.xaml.cs
+++ b/Home Assistant Taskbar Menu/Views/MainWindow.xaml.cs
@@ -4,10 +4,12 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using System.Windows.Interop;
using System.Windows.Media;
using Home_Assistant_Taskbar_Menu.Connection;
using Home_Assistant_Taskbar_Menu.Entities;
@@ -34,6 +36,71 @@ public partial class MainWindow : Window
public ObservableCollection Menu { get; set; }
+ #region Hotkeys
+ [DllImport("user32.dll")]
+ private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
+
+ [DllImport("user32.dll")]
+ private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
+
+ private const int HOTKEY_ID = 9000;
+
+ //Modifiers:
+ private const uint MOD_NONE = 0x0000; //(none)
+ private const uint MOD_ALT = 0x0001; //ALT
+ private const uint MOD_CONTROL = 0x0002; //CTRL
+ private const uint MOD_SHIFT = 0x0004; //SHIFT
+ private const uint MOD_WIN = 0x0008; //WINDOWS
+ private const uint KEY_H = 0x48;
+ private const uint KEY_E = 0x45;
+
+ private IntPtr _windowHandle;
+ private HwndSource _source;
+
+ protected override void OnSourceInitialized(EventArgs e)
+ {
+ base.OnSourceInitialized(e);
+
+ _windowHandle = new WindowInteropHelper(this).Handle;
+ _source = HwndSource.FromHwnd(_windowHandle);
+ _source.AddHook(HwndHook);
+
+ RegisterHotKey(_windowHandle, HOTKEY_ID, MOD_WIN | MOD_SHIFT, KEY_H); // WIN + SHIFT + H
+ RegisterHotKey(_windowHandle, HOTKEY_ID, MOD_WIN | MOD_SHIFT, KEY_E); // WIN + SHIFT + E
+ }
+
+ private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ {
+ const int WM_HOTKEY = 0x0312;
+ switch (msg)
+ {
+ case WM_HOTKEY:
+ switch (wParam.ToInt32())
+ {
+ case HOTKEY_ID:
+ int vkey = (((int)lParam >> 16) & 0xFFFF);
+ if (vkey == KEY_H)
+ {
+ ToggleBrowser(null, null);
+ } else if (vkey == KEY_E) {
+ UIElement_OnKeyDown(null, null);
+ }
+ handled = true;
+ break;
+ }
+ break;
+ }
+ return IntPtr.Zero;
+ }
+
+ protected override void OnClosed(EventArgs e)
+ {
+ _source.RemoveHook(HwndHook);
+ UnregisterHotKey(_windowHandle, HOTKEY_ID);
+ base.OnClosed(e);
+ }
+ #endregion
+
public MainWindow(Configuration configuration, ViewConfiguration viewConfiguration)
{
var latestVersion = ResourceProvider.LatestVersion();
@@ -80,7 +147,7 @@ private List CreateDefaultMenuItems(Configuration configuratio
}
});
CreateMenuIcon(grid, PackIconKind.HomeAssistant, "Open Home Assistant",
- () => ShowBrowser(null, null));
+ () => ToggleBrowser(null, null));
CreateMenuIcon(grid, PackIconKind.OpenInBrowser, "Open Home Assistant in Browser",
() => Process.Start(configuration.HttpUrl()));
CreateMenuIcon(grid, PackIconKind.About, "About HA Taskbar Menu", () =>
@@ -224,7 +291,7 @@ private void UpdateTree(bool authenticated = true)
private void UIElement_OnKeyDown(object sender, KeyEventArgs e)
{
_searchWindow?.Close();
- _searchWindow = new SearchWindow(e.Key.ToString(), _stateObjects);
+ _searchWindow = new SearchWindow(e, _stateObjects);
_searchWindow.ShowDialog();
}
@@ -251,10 +318,20 @@ private Icon GetIcon()
}
}
- private void ShowBrowser(object sender, RoutedEventArgs e)
+ private void ToggleBrowser(object sender, RoutedEventArgs e)
+ {
+ if(_browserWindow.Visibility != Visibility.Visible)
{
_browserWindow.Show();
_browserWindow.Activate();
+ Debug.WriteLine("Showing browser window.");
+ }
+ else
+ {
+ _browserWindow.Hide();
+ Debug.WriteLine("Hiding browser window.");
+ }
+
}
}
}
\ No newline at end of file
diff --git a/Home Assistant Taskbar Menu/Views/SearchWindow.xaml.cs b/Home Assistant Taskbar Menu/Views/SearchWindow.xaml.cs
index e22e6b1..39a867c 100644
--- a/Home Assistant Taskbar Menu/Views/SearchWindow.xaml.cs
+++ b/Home Assistant Taskbar Menu/Views/SearchWindow.xaml.cs
@@ -16,7 +16,7 @@ public partial class SearchWindow : Window
{
private readonly List _entities;
- public SearchWindow(string s, List entities)
+ public SearchWindow(KeyEventArgs s, List entities)
{
_entities = new List(entities);
InitializeComponent();
@@ -29,9 +29,9 @@ public SearchWindow(string s, List entities)
Dispatcher.Invoke(() => UpdateFoundList(null, null));
}
});
- if (s.Length == 1)
+ if (s != null && s.Key.ToString().Length == 1)
{
- SearchBox.Text = s;
+ SearchBox.Text = s.Key.ToString();
}
SearchBox.CaretIndex = int.MaxValue;
diff --git a/Home Assistant Taskbar Menu/Views/ViewConfigurationDialog.xaml.cs b/Home Assistant Taskbar Menu/Views/ViewConfigurationDialog.xaml.cs
index f31dbcb..2617142 100644
--- a/Home Assistant Taskbar Menu/Views/ViewConfigurationDialog.xaml.cs
+++ b/Home Assistant Taskbar Menu/Views/ViewConfigurationDialog.xaml.cs
@@ -15,17 +15,19 @@ public partial class ViewConfigurationDialog : Window
public ViewConfiguration ViewConfiguration { get; set; }
- public ViewConfigurationDialog(List stateObjects)
+ public ViewConfigurationDialog(List stateObjects, ViewConfigurationWindow owner)
{
InitializeComponent();
+ this.Owner = owner;
stateObjects.ForEach(s => EntityIdComboBox.Items.Add(s));
NameTextBox.ToolTip = "Leave empty to use name retrieved from Home Assistant";
_isEntity = true;
}
- public ViewConfigurationDialog()
+ public ViewConfigurationDialog(ViewConfigurationWindow owner)
{
InitializeComponent();
+ this.Owner = owner;
RowEntityId1.Height = new GridLength(0);
RowEntityId2.Height = new GridLength(0);
Height = 130;
diff --git a/Home Assistant Taskbar Menu/Views/ViewConfigurationWindow.xaml b/Home Assistant Taskbar Menu/Views/ViewConfigurationWindow.xaml
index ba4ca48..f880490 100644
--- a/Home Assistant Taskbar Menu/Views/ViewConfigurationWindow.xaml
+++ b/Home Assistant Taskbar Menu/Views/ViewConfigurationWindow.xaml
@@ -46,7 +46,7 @@
-
+
-
+