From a27c8e0060eb6d0b39a68d2d9af7c1bd257805c5 Mon Sep 17 00:00:00 2001 From: omster Date: Thu, 22 Jan 2026 19:04:54 +0000 Subject: [PATCH 1/6] Add: - Location - Inverse scroll option --- WinJump/Core/Config.cs | 43 ++++++++++++++++++++++++++++------ WinJump/Core/WinJumpManager.cs | 14 ++++++----- WinJump/UI/TrayModel.cs | 22 +++++++++++++++++ WinJump/UI/TrayResources.xaml | 5 ++++ 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/WinJump/Core/Config.cs b/WinJump/Core/Config.cs index 033eb25..b1e3b10 100644 --- a/WinJump/Core/Config.cs +++ b/WinJump/Core/Config.cs @@ -1,9 +1,10 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; -using Newtonsoft.Json; namespace WinJump.Core; @@ -30,7 +31,10 @@ internal sealed class Config { [JsonProperty("change-desktops-with-scroll")] public required bool ChangeDesktopsWithScroll { get; set; } - + + [JsonProperty("scroll-invert-direction")] + public required bool ScrollInvertDirection { get; set; } + [JsonProperty("sticky-desktops")] public int StickyDesktops { get; set; } @@ -95,11 +99,35 @@ public static Config Load() { } public static void EnsureCreated() { - if(File.Exists(LOCATION)) return; + var defaults = JObject.FromObject(Default()); + + // Create a file if it's not there + if (!File.Exists(LOCATION)) + { + File.WriteAllText(LOCATION, defaults.ToString(Formatting.Indented)); + return; + } + + //Update a file with new options + var existing = JObject.Parse(File.ReadAllText(LOCATION)); + bool changed = false; - var config = Default(); - string content = JsonConvert.SerializeObject(config, Formatting.Indented); - File.WriteAllText(LOCATION, content); + foreach (var prop in defaults.Properties()) + { + if (existing[prop.Name] == null) + { + existing[prop.Name] = prop.Value; + changed = true; + } + } + + if (changed) + { + File.WriteAllText( + LOCATION, + existing.ToString(Formatting.Indented) + ); + } } /// @@ -133,6 +161,7 @@ private static Config Default() { ToggleGroups = [], JumpCurrentGoesToLast = true, ChangeDesktopsWithScroll = false, + ScrollInvertDirection = false, StickyDesktops = 0 }; } diff --git a/WinJump/Core/WinJumpManager.cs b/WinJump/Core/WinJumpManager.cs index f4d37b1..630eafa 100644 --- a/WinJump/Core/WinJumpManager.cs +++ b/WinJump/Core/WinJumpManager.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Win32; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -131,11 +132,12 @@ public WinJumpManager(DesktopChanged desktopChanged) { int? current = _thread?.GetCurrentDesktop(); if(current != null) { - if(args.up) { - _thread?.JumpToNoHack((uint) (current.Value + 1)); - } else { - _thread?.JumpToNoHack((uint) (current.Value - 1)); - } + int delta = args.up ? 1 : -1; + + if (config.ScrollInvertDirection) + delta = -delta; + + _thread?.JumpToNoHack((uint)(current.Value + delta)); } }; diff --git a/WinJump/UI/TrayModel.cs b/WinJump/UI/TrayModel.cs index 57e1eb3..06bf8e0 100644 --- a/WinJump/UI/TrayModel.cs +++ b/WinJump/UI/TrayModel.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Diagnostics; using System.Reflection; using System.Windows; @@ -9,6 +10,8 @@ namespace WinJump.UI; public class TrayModel { + + private bool _startWithWindows; public ICommand OnOpenConfig => new DelegateCommand { CanExecuteFunc = () => true, CommandAction = () => { @@ -52,6 +55,25 @@ public class TrayModel { } }; + public ICommand OnOpenLocation => new DelegateCommand + { + CanExecuteFunc = () => true, + CommandAction = () => { + Config.EnsureCreated(); + + if (!File.Exists(Config.LOCATION)) + return; + + Process.Start(new ProcessStartInfo + { + FileName = "explorer.exe", + Arguments = $"/select,\"{Config.LOCATION}\"", + UseShellExecute = true + }); + + } + }; + public ICommand Exit => new DelegateCommand { CanExecuteFunc = () => true, CommandAction = () => { diff --git a/WinJump/UI/TrayResources.xaml b/WinJump/UI/TrayResources.xaml index fcbfd85..7f702ff 100644 --- a/WinJump/UI/TrayResources.xaml +++ b/WinJump/UI/TrayResources.xaml @@ -11,6 +11,11 @@ + + From 30a37dba7aae5ee4188aef1fed86b054d1436e7e Mon Sep 17 00:00:00 2001 From: omster Date: Fri, 23 Jan 2026 17:10:18 +0000 Subject: [PATCH 2/6] Working start-with-windows checkbox --- WinJump/Core/Config.cs | 102 ++++++++++++++++++--------------- WinJump/Core/WinJumpManager.cs | 30 +++++++++- WinJump/UI/App.xaml.cs | 6 +- WinJump/UI/TrayModel.cs | 38 +++++++++++- WinJump/UI/TrayResources.xaml | 7 ++- 5 files changed, 130 insertions(+), 53 deletions(-) diff --git a/WinJump/Core/Config.cs b/WinJump/Core/Config.cs index b1e3b10..511185f 100644 --- a/WinJump/Core/Config.cs +++ b/WinJump/Core/Config.cs @@ -17,6 +17,11 @@ internal sealed class Config { Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".winjump"); + public static Config Current { get; private set; } = null!; + + [JsonProperty("enable-startup")] + public required bool EnableStartup { get; set; } + [JsonProperty("move-window-to")] public required List MoveWindowTo { get; set; } @@ -38,63 +43,66 @@ internal sealed class Config { [JsonProperty("sticky-desktops")] public int StickyDesktops { get; set; } - public static Config Load() { - try { + public static Config Load() + { + try + { EnsureCreated(); string content = File.ReadAllText(LOCATION); - var config = JsonConvert.DeserializeObject(content); + var config = JsonConvert.DeserializeObject(content) ?? throw new Exception("Failed to deserialize config file"); - if(config == null) { - throw new Exception("Failed to deserialize config file"); - } + Validate(config); - // Check for jump tos with duplicate shortcuts - for(int i = 0; i < config.JumpTo.Count; i++) { - var shortcut = config.JumpTo[i].Shortcut; - for(int j = i + 1; j < config.JumpTo.Count; j++) { - if(config.JumpTo[j].Shortcut.IsEqual(shortcut)) { - throw new Exception("Duplicate jump to shortcut"); - } - - if(config.JumpTo[i].Desktop <= 0) { - throw new Exception("Invalid desktop number"); - } - } + Current = config; + return config; + } + catch + { + Current = Default(); + return Current; + } + } + private static void Validate(Config config) + { + // JumpTo duplicates + for (int i = 0; i < config.JumpTo.Count; i++) { + var shortcut = config.JumpTo[i].Shortcut; + + if (config.JumpTo[i].Desktop <= 0) + throw new Exception("Invalid desktop number"); + + for (int j = i + 1; j < config.JumpTo.Count; j++) { + if (config.JumpTo[j].Shortcut.IsEqual(shortcut)) + throw new Exception("Duplicate jump to shortcut"); } + } - // Check for toggle groups with duplicate shortcuts - for(int i = 0; i < config.ToggleGroups.Count; i++) { - var shortcut = config.ToggleGroups[i].Shortcut; - for(int j = i + 1; j < config.ToggleGroups.Count; j++) { - if(config.ToggleGroups[j].Shortcut.IsEqual(shortcut)) { - throw new Exception("Duplicate toggle group shortcut"); - } - - if(config.ToggleGroups[i].Desktops.Any((d) => d <= 0)) { - throw new Exception("Invalid desktop number"); - } - } - } + // ToggleGroups + for (int i = 0; i < config.ToggleGroups.Count; i++) { + var shortcut = config.ToggleGroups[i].Shortcut; + + if (config.ToggleGroups[i].Desktops.Any(d => d <= 0)) + throw new Exception("Invalid desktop number"); - // Check for move windows with duplicate shortcuts - for(int i = 0; i < config.MoveWindowTo.Count; i++) { - var shortcut = config.MoveWindowTo[i].Shortcut; - for(int j = i + 1; j < config.MoveWindowTo.Count; j++) { - if(config.MoveWindowTo[j].Shortcut.IsEqual(shortcut)) { - throw new Exception("Duplicate move window shortcut"); - } - - if(config.MoveWindowTo[i].Desktop <= 0) { - throw new Exception("Invalid desktop number"); - } - } + for (int j = i + 1; j < config.ToggleGroups.Count; j++) { + if (config.ToggleGroups[j].Shortcut.IsEqual(shortcut)) + throw new Exception("Duplicate toggle group shortcut"); } + } - return config; - } catch(Exception) { - return Default(); + // MoveWindowTo + for (int i = 0; i < config.MoveWindowTo.Count; i++) { + var shortcut = config.MoveWindowTo[i].Shortcut; + + if (config.MoveWindowTo[i].Desktop <= 0) + throw new Exception("Invalid desktop number"); + + for (int j = i + 1; j < config.MoveWindowTo.Count; j++) { + if (config.MoveWindowTo[j].Shortcut.IsEqual(shortcut)) + throw new Exception("Duplicate move window shortcut"); + } } } @@ -135,6 +143,7 @@ public static void EnsureCreated() { /// /// Default configuration private static Config Default() { + var jumpTo = new List(); uint desktop = 1; @@ -157,6 +166,7 @@ private static Config Default() { Desktop = x.Desktop, Follow = false }).ToList(), + EnableStartup = true, JumpTo = jumpTo, ToggleGroups = [], JumpCurrentGoesToLast = true, diff --git a/WinJump/Core/WinJumpManager.cs b/WinJump/Core/WinJumpManager.cs index 630eafa..5e832ef 100644 --- a/WinJump/Core/WinJumpManager.cs +++ b/WinJump/Core/WinJumpManager.cs @@ -37,14 +37,24 @@ public class WinJumpManager : IDisposable { private uint _currentDesktop { get; set; } private uint? _lastDesktop { get; set; } + private const string RUN_KEY = @"Software\Microsoft\Windows\CurrentVersion\Run"; + private const string APP_NAME = "WinJump"; + + private static string AppPath => + Process.GetCurrentProcess().MainModule!.FileName!; + public static bool LastLoadRequiredExplorerRestart; public WinJumpManager(DesktopChanged desktopChanged) { // Load config file var config = Config.Load(); - // Attempt to register the shortcuts. + if (config.EnableStartup) + EnableStartup(); + else + DisableStartup(); + // Attempt to register the shortcuts. var registerShortcuts = new List> { () => { return config.JumpTo.Select(t => t.Shortcut).All(shortcut => @@ -178,6 +188,24 @@ public WinJumpManager(DesktopChanged desktopChanged) { }; } + public static void EnableStartup() + { + using var key = Registry.CurrentUser.OpenSubKey(RUN_KEY, true); + key!.SetValue(APP_NAME, $"\"{AppPath}\""); + } + + public static void DisableStartup() + { + using var key = Registry.CurrentUser.OpenSubKey(RUN_KEY, true); + key!.DeleteValue(APP_NAME, false); + } + + public static bool IsStartupEnabled() + { + using var key = Registry.CurrentUser.OpenSubKey(RUN_KEY, false); + return key?.GetValue(APP_NAME) != null; + } + public void Dispose() { _thread?.Dispose(); _explorerMonitor.Dispose(); diff --git a/WinJump/UI/App.xaml.cs b/WinJump/UI/App.xaml.cs index 79ca527..182902a 100644 --- a/WinJump/UI/App.xaml.cs +++ b/WinJump/UI/App.xaml.cs @@ -25,7 +25,9 @@ protected override void OnStartup(StartupEventArgs e) { return; } - if(FindResource("NotifyIcon") is TaskbarIcon icon) { + Config.Load(); // fix config.current + + if (FindResource("NotifyIcon") is TaskbarIcon icon) { notifyIcon = icon; } else { throw new Exception("Could not find NotifyIcon"); @@ -37,7 +39,7 @@ protected override void OnStartup(StartupEventArgs e) { var lightIcons = new Dictionary(); var darkIcons = new Dictionary(); - for(uint i = 1; i <= 16; i++) { + for (uint i = 1; i <= 16; i++) { string fileName = i > 15 ? "15+.ico" : $"{i}.ico"; var lightFileInfo = embeddedProvider.GetFileInfo("UI/Icons/Light/" + fileName); diff --git a/WinJump/UI/TrayModel.cs b/WinJump/UI/TrayModel.cs index 06bf8e0..da78cbf 100644 --- a/WinJump/UI/TrayModel.cs +++ b/WinJump/UI/TrayModel.cs @@ -6,12 +6,46 @@ using System.Windows.Input; using Microsoft.Win32; using WinJump.Core; +using System.ComponentModel; namespace WinJump.UI; -public class TrayModel { +public class TrayModel : INotifyPropertyChanged{ + + public event PropertyChangedEventHandler? PropertyChanged; + + public bool StartWithWindows + { + get => Config.Current?.EnableStartup ?? false; + set + { + if (Config.Current == null) + return; + + if (Config.Current.EnableStartup == value) + return; + + Config.Current.EnableStartup = value; + + if (value) + WinJumpManager.EnableStartup(); + else + WinJumpManager.DisableStartup(); + + PropertyChanged?.Invoke( + this, + new PropertyChangedEventArgs(nameof(StartWithWindows)) + ); + } + } + + public ICommand ToggleStartWithWindows => new DelegateCommand { + CanExecuteFunc = () => true, + CommandAction = () => { + StartWithWindows = !StartWithWindows; + } + }; - private bool _startWithWindows; public ICommand OnOpenConfig => new DelegateCommand { CanExecuteFunc = () => true, CommandAction = () => { diff --git a/WinJump/UI/TrayResources.xaml b/WinJump/UI/TrayResources.xaml index 7f702ff..51a0790 100644 --- a/WinJump/UI/TrayResources.xaml +++ b/WinJump/UI/TrayResources.xaml @@ -6,23 +6,26 @@ + + - + Command="{Binding ToggleStartWithWindows}" /> + + \ No newline at end of file From 2187c139a4c78c9e14d0f51257168f5d0289fb1f Mon Sep 17 00:00:00 2001 From: omster Date: Sat, 24 Jan 2026 16:00:58 +0000 Subject: [PATCH 3/6] Working on taskbar bug - Start with windows works --- WinJump/Core/Config.cs | 2 +- WinJump/Core/WinJumpManager.cs | 6 +++--- WinJump/UI/App.xaml.cs | 4 ++-- WinJump/UI/TrayModel.cs | 15 +++++++++------ WinJump/UI/TrayResources.xaml | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/WinJump/Core/Config.cs b/WinJump/Core/Config.cs index 511185f..a15bb4e 100644 --- a/WinJump/Core/Config.cs +++ b/WinJump/Core/Config.cs @@ -11,7 +11,7 @@ namespace WinJump.Core; /// /// Handles loading the configuration file /// -internal sealed class Config { +public sealed class Config { public static readonly int MAX_STICKY_DESKTOPS = 10; public static readonly string LOCATION = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), diff --git a/WinJump/Core/WinJumpManager.cs b/WinJump/Core/WinJumpManager.cs index 5e832ef..2575397 100644 --- a/WinJump/Core/WinJumpManager.cs +++ b/WinJump/Core/WinJumpManager.cs @@ -45,9 +45,9 @@ public class WinJumpManager : IDisposable { public static bool LastLoadRequiredExplorerRestart; - public WinJumpManager(DesktopChanged desktopChanged) { - // Load config file - var config = Config.Load(); + public WinJumpManager(Config config, DesktopChanged desktopChanged) { + //// Load config file + //var config = Config.Load(); if (config.EnableStartup) EnableStartup(); diff --git a/WinJump/UI/App.xaml.cs b/WinJump/UI/App.xaml.cs index 182902a..b8cf70d 100644 --- a/WinJump/UI/App.xaml.cs +++ b/WinJump/UI/App.xaml.cs @@ -25,7 +25,7 @@ protected override void OnStartup(StartupEventArgs e) { return; } - Config.Load(); // fix config.current + var config = Config.Load(); // fix config.current if (FindResource("NotifyIcon") is TaskbarIcon icon) { notifyIcon = icon; @@ -52,7 +52,7 @@ protected override void OnStartup(StartupEventArgs e) { darkIcons.Add(i, new Icon(darkStream)); } - manager = new WinJumpManager( + manager = new WinJumpManager(config, (lightMode, desktopIcon) => { notifyIcon.Icon = lightMode ? darkIcons[desktopIcon + 1] : lightIcons[desktopIcon + 1]; }); diff --git a/WinJump/UI/TrayModel.cs b/WinJump/UI/TrayModel.cs index da78cbf..0700666 100644 --- a/WinJump/UI/TrayModel.cs +++ b/WinJump/UI/TrayModel.cs @@ -1,12 +1,13 @@ -using System; -using System.IO; +using Microsoft.Win32; +using Newtonsoft.Json.Linq; +using System; +using System.ComponentModel; using System.Diagnostics; +using System.IO; using System.Reflection; using System.Windows; using System.Windows.Input; -using Microsoft.Win32; using WinJump.Core; -using System.ComponentModel; namespace WinJump.UI; @@ -39,10 +40,13 @@ public bool StartWithWindows } } - public ICommand ToggleStartWithWindows => new DelegateCommand { + public ICommand ToggleStartWithWindows => new DelegateCommand + { CanExecuteFunc = () => true, CommandAction = () => { + StartWithWindows = !StartWithWindows; + Debug.WriteLine($"StartWithWindows set to {StartWithWindows}"); } }; @@ -117,7 +121,6 @@ public bool StartWithWindows var killExplorer = Process.Start("cmd.exe", "/c taskkill /f /im explorer.exe"); killExplorer.WaitForExit(); - Process.Start(Environment.SystemDirectory + "\\..\\explorer.exe"); } diff --git a/WinJump/UI/TrayResources.xaml b/WinJump/UI/TrayResources.xaml index 51a0790..cc6d0d3 100644 --- a/WinJump/UI/TrayResources.xaml +++ b/WinJump/UI/TrayResources.xaml @@ -7,7 +7,7 @@ MenuActivation="LeftOrRightClick"> - + From 6bf5e4691e8442184efd25a076349e80804619c5 Mon Sep 17 00:00:00 2001 From: omster Date: Mon, 26 Jan 2026 16:44:38 +0000 Subject: [PATCH 4/6] Added the fullscreen check & icon --- WinJump/Core/WinJumpManager.cs | 114 +++++++++++++++++++++++++++++++-- WinJump/UI/Icons/app.ico | Bin 0 -> 9662 bytes WinJump/WinJump.csproj | 2 + 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 WinJump/UI/Icons/app.ico diff --git a/WinJump/Core/WinJumpManager.cs b/WinJump/Core/WinJumpManager.cs index 2575397..4583489 100644 --- a/WinJump/Core/WinJumpManager.cs +++ b/WinJump/Core/WinJumpManager.cs @@ -1,10 +1,11 @@ using Microsoft.Win32; using System; +using System.Runtime.InteropServices; +using System.Text; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Windows; @@ -16,6 +17,7 @@ namespace WinJump.Core; public delegate void DesktopChanged(bool lightMode, uint desktopNum); + /// /// Ties everything together. /// @@ -25,21 +27,68 @@ namespace WinJump.Core; /// and that color scheme / taskbar created events are handled. /// public class WinJumpManager : IDisposable { + + // Structs for the Windows Taskbar position - Win32 Shell API. + public struct RECT + { + public int left, top, right, bottom; + } + public struct APPBARDATA + { + public int cbSize; + public IntPtr hWnd; + public uint uCallbackMessage; + public uint uEdge; + public RECT rc; + public int lParam; + } + /* * Internal fields */ - private readonly STAThread? _thread; // tied exactly to the lifecycle of explorer.exe private readonly ExplorerMonitor _explorerMonitor = new(); private readonly KeyboardHook _keyboardHook = new(); private readonly MouseHook _mouseHook = new(); + + #region P/Invoke Signatures + + [DllImport("user32.dll")] + static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + static extern IntPtr GetShellWindow(); + + [DllImport("user32.dll")] + static extern IntPtr GetDesktopWindow(); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("user32.dll")] + static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect); + + [DllImport("user32.dll")] + static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("shell32.dll")] + private static extern uint SHAppBarMessage(uint dwMessage, ref APPBARDATA pData); + + #endregion + + private const uint ABM_GETSTATE = 0x00000004; + private const uint ABM_GETTASKBARPOS = 0x00000005; + + const int GWL_STYLE = -16; + const uint WS_CAPTION = 0x00C00000; // Title bar style + private bool _lightMode { get; set; } private uint _currentDesktop { get; set; } private uint? _lastDesktop { get; set; } private const string RUN_KEY = @"Software\Microsoft\Windows\CurrentVersion\Run"; private const string APP_NAME = "WinJump"; - + private uint? taskbarState = null; private static string AppPath => Process.GetCurrentProcess().MainModule!.FileName!; @@ -87,6 +136,7 @@ public WinJumpManager(Config config, DesktopChanged desktopChanged) { if(config.ChangeDesktopsWithScroll) { _mouseHook.Register(); + taskbarState = GetTaskbarState(); } // Add handler for hotkey press events @@ -134,10 +184,16 @@ public WinJumpManager(Config config, DesktopChanged desktopChanged) { } }; + // Add a handler for mouse scroll events _mouseHook.MouseScrolled += (_, args) => { - // Check to make sure the mouse event happened over the taskbar - if(args.y < SystemParameters.PrimaryScreenHeight - 40) return; + //Check if the mouse event happened over the taskbar + if (args.y < SystemParameters.PrimaryScreenHeight - 40) return; + + // Check the focused window + bool bIsIt = IsActiveWindowAGame(); + System.Diagnostics.Debug.WriteLine("IsActiveWindowAGame: {0}", bIsIt); + if (bIsIt) return; int? current = _thread?.GetCurrentDesktop(); @@ -188,6 +244,54 @@ public WinJumpManager(Config config, DesktopChanged desktopChanged) { }; } + public bool IsActiveWindowAGame() + { + IntPtr hWnd = GetForegroundWindow(); + + if (hWnd == IntPtr.Zero) return false; + + // edge case, if the focused window is the desktop or taskbar, it's not a game + if (hWnd == GetShellWindow() || hWnd == GetDesktopWindow()) return false; + + // edge case, Windows uses 'WorkerW' or 'Progman' for the wallpaper/icons + // These always report as full-screen size, so we must filter them by class name. + StringBuilder className = new StringBuilder(256); + GetClassName(hWnd, className, 256); + string cName = className.ToString(); + if (cName == "WorkerW" || cName == "Progman") return false; + + // Check if it covers the screen (maximised & borderless) + GetWindowRect(hWnd, out RECT rect); + var screen = System.Windows.Forms.Screen.FromHandle(hWnd); + bool isFullScreenSize = (rect.right - rect.left >= screen.Bounds.Width && + rect.bottom - rect.top >= screen.Bounds.Height); + + if (!isFullScreenSize) return false; + + // Goofy check: Check window style since games apparently lack a Title Bar WS_CAPTION + long style = GetWindowLong(hWnd, GWL_STYLE); + bool hasNoTitleBar = (style & WS_CAPTION) == 0; + + // If it fills the screen and has no title bar, its a game or a full video + return hasNoTitleBar; + } + + + /* + * Returns 1 if taskbar auto-hidden, 0 otherwise. + */ + private static uint? GetTaskbarState() + { + var data = new APPBARDATA + { + cbSize = Marshal.SizeOf() + }; + + var appBarMessage = SHAppBarMessage(ABM_GETSTATE, ref data); + System.Diagnostics.Debug.WriteLine("appBarState, state: {0}", appBarMessage); + return appBarMessage; + } + public static void EnableStartup() { using var key = Registry.CurrentUser.OpenSubKey(RUN_KEY, true); diff --git a/WinJump/UI/Icons/app.ico b/WinJump/UI/Icons/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..8640ad0a1665986c9918feee69fb41e95fbc711b GIT binary patch literal 9662 zcmeI1KZsma6vp3@Vw=EPiCtbJ2sR68g-uEe3%gAhn-q3JiXefE2&Rl!C;??Hf&?rq z)oKTXh`1maB8bsli4qfIvN8WA$;RjJdo%ZW=ghfp-rdO-!kqBs+;i@^=X~$Jd+*$t zEs6#HEiV`RUl!+|FN$Z2qIdz|DvkpA=kouXfvTzs5Al@NA*V$^44T6|l-&E?o7z8=^dLG9AZ ziGM#h0ye-M@Ci6*WAQaYpK`qqZUV_Ya0#q|V_+HV2g!BTB=Z|@;=Ttoal%9Ju9px0 zVQ>?KSm_(!r8pkD5&S*y7_>>~|Bj%S!NjvP2`3xh;)?mGeG5#?3BI#Vtm4ndHL)AP zzX@{W0l`PWSp6p9WaCdD2=k5VG zX#8>TCAbJKgKI$Rcw#b3M_d);{eovZqM zsPj7fb*7~F=KA$~?jCUJPPpLsw!>d8ea5Bu>#Kstvu#g%@xk|5s3n~v#6Jff0W0Tl zH1E~qTy^+sKfDHhbNT|$l-9Z3)KWV~h}W58MW4w{PLuDX!%=gfuoCDlk>cv@2c4s3 zOFg>N!ngsj@(Yd>|8r!s{4@u3JbfPmkEb0I+o!{L=^P>c7O?Uwjuih3oTJXMo!Ul^mk zYQ^%22Vcerd>T!HxVFyN4}jKo6GQtFD2*@l>y8lTAZ)rY#ydmn{TT9@EZ49@&7f~P zu_bZ3kNyp`r#HYWKyn*|v5gKnq`L~SCxDeU{tukmpOc`TyN-4BEDi5bTlbmW%zrL_ zo%ObM+vlD4NN1cJT5B(cXYdAjKH_uur|u4I_YJSCz8Bazko|GsFWp5l`KRhmyYE>l zng{O=-t412;_topX0KS1Q|v$Jx9?!E$MgS{Q}eG-a|&PE{f(3BZpgJq^Y49j#h<;F zW1H>0ORcG_wa9bk>|cE^wC{Yk>nF9BR&(9~v2Oq?4JSI{IeeP@Q+xPp)eMM>du`(M zyjI4(*G1zz{`LJmipgotyoVvKv)dDI9eQ`4pBS9OIga)A@Yvi<%T2#{dQyKT#l>iQ zcb^LkHesDjZx8GDoo4-X$xV!&*-E{S3={88yk=r@Om`1MB$t2qEjNCK*OkYJy$>tk zn2E_T-97x2_XnX5l_xQM$elyV=&LZm!j&rJh?)upX zq(@qR>!{BkLu?H@-2bIz&nm}B5dSSC>-G*K=UVmDoo?Z=_4~tWuKT z9iZQieh2S?Yzcg=&Q3HRFrR_>49sU>4`zU~Nyn4U)lRxUIM81rzCT#%FG!zQ>KCWb z%aLBeerB;>NEeG$Z=|;l4DD@nuh>^vJ;47~u~5~zXLP?9`h(s&G_2.0.15 2.0.15 2.0.15 + UI\Icons\app.ico @@ -114,6 +115,7 @@ + From ca1b34d19c2bf97554383e6ef852320decf25675 Mon Sep 17 00:00:00 2001 From: omster Date: Mon, 26 Jan 2026 16:59:44 +0000 Subject: [PATCH 5/6] Fix StartWithWindows tray interaction --- WinJump/UI/TrayModel.cs | 38 +++++++++++++---------------------- WinJump/UI/TrayResources.xaml | 2 +- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/WinJump/UI/TrayModel.cs b/WinJump/UI/TrayModel.cs index 0700666..b8ee217 100644 --- a/WinJump/UI/TrayModel.cs +++ b/WinJump/UI/TrayModel.cs @@ -15,39 +15,29 @@ public class TrayModel : INotifyPropertyChanged{ public event PropertyChangedEventHandler? PropertyChanged; - public bool StartWithWindows + public static bool StartWithWindows => Config.Current.EnableStartup; + + public ICommand ToggleStartWithWindows => new DelegateCommand { - get => Config.Current?.EnableStartup ?? false; - set + CanExecuteFunc = () => true, + CommandAction = () => { - if (Config.Current == null) - return; - - if (Config.Current.EnableStartup == value) - return; - - Config.Current.EnableStartup = value; - - if (value) - WinJumpManager.EnableStartup(); - else + if (Config.Current.EnableStartup) + { WinJumpManager.DisableStartup(); + Config.Current.EnableStartup = false; + } + else + { + WinJumpManager.EnableStartup(); + Config.Current.EnableStartup = true; + } PropertyChanged?.Invoke( this, new PropertyChangedEventArgs(nameof(StartWithWindows)) ); } - } - - public ICommand ToggleStartWithWindows => new DelegateCommand - { - CanExecuteFunc = () => true, - CommandAction = () => { - - StartWithWindows = !StartWithWindows; - Debug.WriteLine($"StartWithWindows set to {StartWithWindows}"); - } }; public ICommand OnOpenConfig => new DelegateCommand { diff --git a/WinJump/UI/TrayResources.xaml b/WinJump/UI/TrayResources.xaml index cc6d0d3..7822623 100644 --- a/WinJump/UI/TrayResources.xaml +++ b/WinJump/UI/TrayResources.xaml @@ -16,7 +16,7 @@ From 26adc761c1f420d4bf646dc0d70a3eecac6336e1 Mon Sep 17 00:00:00 2001 From: omster Date: Mon, 26 Jan 2026 17:07:36 +0000 Subject: [PATCH 6/6] Actually restructure StartWithWindows debugging behaviour --- WinJump/Core/Config.cs | 4 ---- WinJump/Core/WinJumpManager.cs | 2 +- WinJump/UI/TrayModel.cs | 6 ++---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/WinJump/Core/Config.cs b/WinJump/Core/Config.cs index a15bb4e..e755254 100644 --- a/WinJump/Core/Config.cs +++ b/WinJump/Core/Config.cs @@ -19,9 +19,6 @@ public sealed class Config { public static Config Current { get; private set; } = null!; - [JsonProperty("enable-startup")] - public required bool EnableStartup { get; set; } - [JsonProperty("move-window-to")] public required List MoveWindowTo { get; set; } @@ -166,7 +163,6 @@ private static Config Default() { Desktop = x.Desktop, Follow = false }).ToList(), - EnableStartup = true, JumpTo = jumpTo, ToggleGroups = [], JumpCurrentGoesToLast = true, diff --git a/WinJump/Core/WinJumpManager.cs b/WinJump/Core/WinJumpManager.cs index 4583489..4474b03 100644 --- a/WinJump/Core/WinJumpManager.cs +++ b/WinJump/Core/WinJumpManager.cs @@ -98,7 +98,7 @@ public WinJumpManager(Config config, DesktopChanged desktopChanged) { //// Load config file //var config = Config.Load(); - if (config.EnableStartup) + if (IsStartupEnabled()) EnableStartup(); else DisableStartup(); diff --git a/WinJump/UI/TrayModel.cs b/WinJump/UI/TrayModel.cs index b8ee217..c005567 100644 --- a/WinJump/UI/TrayModel.cs +++ b/WinJump/UI/TrayModel.cs @@ -15,22 +15,20 @@ public class TrayModel : INotifyPropertyChanged{ public event PropertyChangedEventHandler? PropertyChanged; - public static bool StartWithWindows => Config.Current.EnableStartup; + public static bool StartWithWindows => WinJumpManager.IsStartupEnabled(); public ICommand ToggleStartWithWindows => new DelegateCommand { CanExecuteFunc = () => true, CommandAction = () => { - if (Config.Current.EnableStartup) + if (WinJumpManager.IsStartupEnabled()) { WinJumpManager.DisableStartup(); - Config.Current.EnableStartup = false; } else { WinJumpManager.EnableStartup(); - Config.Current.EnableStartup = true; } PropertyChanged?.Invoke(