From 75afc1bea88115235986b3b91a3902f5477820c5 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Mon, 19 Dec 2016 11:53:06 +0100 Subject: [PATCH 01/16] Fixed wrong ActiveWindow-Parameters through observing window-title-changes and un-minimizing --- .../Artemis/Utilities/ActiveWindowHelper.cs | 82 ++++++++++++++++--- 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/Artemis/Artemis/Utilities/ActiveWindowHelper.cs b/Artemis/Artemis/Utilities/ActiveWindowHelper.cs index 2b4e712f7..d072440b9 100644 --- a/Artemis/Artemis/Utilities/ActiveWindowHelper.cs +++ b/Artemis/Artemis/Utilities/ActiveWindowHelper.cs @@ -21,13 +21,15 @@ namespace Artemis.Utilities [DllImport("user32.dll")] private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId); - + #endregion #region Constants - private const uint WINEVENT_OUTOFCONTEXT = 0; - private const uint EVENT_SYSTEM_FOREGROUND = 3; + private const uint WINEVENT_OUTOFCONTEXT = 0x0000; + private const uint EVENT_SYSTEM_FOREGROUND = 0x0003; + private const uint EVENT_OBJECT_NAMECHANGE = 0x800C; + private const uint EVENT_SYSTEM_MINIMIZEEND = 0x0017; private const int MAX_TITLE_LENGTH = 256; @@ -37,7 +39,15 @@ namespace Artemis.Utilities // DarthAffe 17.12.2016: We need to keep a reference to this or it might get collected by the garbage collector and cause some random crashes afterwards. private static WinEventDelegate _activeWindowChangedDelegate; - private static IntPtr _winEventHook; + private static IntPtr _activeWindowEventHook; + + private static WinEventDelegate _windowTitleChangedDelegate; + private static IntPtr _windowTitleEventHook; + + private static WinEventDelegate _windowMinimizedChangedDelegate; + private static IntPtr _windowMinimizedEventHook; + + private static IntPtr _activeWindow; public static string ActiveWindowProcessName { get; private set; } public static string ActiveWindowWindowTitle { get; private set; } @@ -49,6 +59,28 @@ namespace Artemis.Utilities private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) { + UpdateForWindow(hwnd); + } + + private static void WindowTitleChanged(IntPtr hWinEventHook, uint eventType, + IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) + { + if (_activeWindow == hwnd) + UpdateForWindow(hwnd); + } + + private static void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType, + IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) + { + // DarthAffe 19.12.2016: We expect currently un-minimized windows to be active. + // DarthAffe 19.12.2016: The result of the API-function GetActiveWindow at this moment is 'idle' so we can't use this to validate this estimation. + UpdateForWindow(hwnd); + } + + private static void UpdateForWindow(IntPtr hwnd) + { + _activeWindow = hwnd; + ActiveWindowProcessName = GetActiveWindowProcessName(hwnd) ?? string.Empty; ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty; } @@ -84,10 +116,23 @@ namespace Artemis.Utilities { try { - if (_winEventHook != IntPtr.Zero) return; + if (_activeWindowEventHook == IntPtr.Zero) + { + _activeWindowChangedDelegate = ActiveWindowChanged; + _activeWindowEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); + } - _activeWindowChangedDelegate = ActiveWindowChanged; - _winEventHook = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, IntPtr.Zero, _activeWindowChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); + if (_windowTitleEventHook == IntPtr.Zero) + { + _windowTitleChangedDelegate = WindowTitleChanged; + _windowTitleEventHook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, IntPtr.Zero, _windowTitleChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); + } + + if (_windowMinimizedEventHook == IntPtr.Zero) + { + _windowMinimizedChangedDelegate = WindowMinimizedChanged; + _windowMinimizedEventHook = SetWinEventHook(EVENT_SYSTEM_MINIMIZEEND, EVENT_SYSTEM_MINIMIZEEND, IntPtr.Zero, _windowMinimizedChangedDelegate, 0, 0, WINEVENT_OUTOFCONTEXT); + } } catch { /* catch'em all - I don't want it to crash here */ } } @@ -96,11 +141,26 @@ namespace Artemis.Utilities { try { - if (_winEventHook == IntPtr.Zero) return; + if (_activeWindowEventHook != IntPtr.Zero) + { + UnhookWinEvent(_activeWindowEventHook); + _activeWindowChangedDelegate = null; + _activeWindowEventHook = IntPtr.Zero; + } - UnhookWinEvent(_winEventHook); - _activeWindowChangedDelegate = null; - _winEventHook = IntPtr.Zero; + if (_windowTitleEventHook != IntPtr.Zero) + { + UnhookWinEvent(_windowTitleEventHook); + _windowTitleChangedDelegate = null; + _windowTitleEventHook = IntPtr.Zero; + } + + if (_windowMinimizedEventHook != IntPtr.Zero) + { + UnhookWinEvent(_windowMinimizedEventHook); + _windowMinimizedChangedDelegate = null; + _windowMinimizedEventHook = IntPtr.Zero; + } } catch { /* catch'em all - I don't want it to crash here */ } } From 21b7132ada12ba5ff9cbbe185a44b13c73327eda Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Mon, 19 Dec 2016 13:57:43 +0100 Subject: [PATCH 02/16] Added condition type to layers to resolve #244 --- .../Layers/Conditions/DataModelCondition.cs | 15 +++++++++-- .../Layers/Conditions/EventCondition.cs | 17 ++++++++++-- .../Profiles/Layers/Models/LayerModel.cs | 2 +- .../Layers/Models/LayerPropertiesModel.cs | 10 +++++++ .../Profiles/LayerEditorViewModel.cs | 2 +- .../Views/Flyouts/FlyoutSettingsView.xaml | 1 - .../Views/Profiles/LayerEditorView.xaml | 27 ++++++++++++++++++- 7 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs index 3572d0e74..29f388749 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/DataModelCondition.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -11,7 +12,17 @@ namespace Artemis.Profiles.Layers.Conditions { lock (layerModel.Properties.Conditions) { - return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + switch (layerModel.Properties.ConditionType) + { + case ConditionType.AnyMet: + return layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel)); + case ConditionType.AllMet: + return layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + case ConditionType.NoneMet: + return !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel)); + default: + throw new ArgumentOutOfRangeException(); + } } } } diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs index 04ea65aa8..902331477 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using Artemis.Models.Interfaces; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; @@ -11,7 +12,19 @@ namespace Artemis.Profiles.Layers.Conditions { lock (layerModel.Properties.Conditions) { - var conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + var conditionsMet = false; + switch (layerModel.Properties.ConditionType) + { + case ConditionType.AnyMet: + conditionsMet = layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel)); + break; + case ConditionType.AllMet: + conditionsMet = layerModel.Properties.Conditions.All(cm => cm.ConditionMet(dataModel)); + break; + case ConditionType.NoneMet: + conditionsMet = !layerModel.Properties.Conditions.Any(cm => cm.ConditionMet(dataModel)); + break; + } layerModel.EventProperties.Update(layerModel, conditionsMet); if (conditionsMet && layerModel.EventProperties.CanTrigger) diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs index 53cee288d..5870cdb19 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerModel.cs @@ -387,7 +387,7 @@ namespace Artemis.Profiles.Layers.Models get { return Profile; } set { Profile = value; } } - + #endregion } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs index ccf0d77c5..c8720f1a4 100644 --- a/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs +++ b/Artemis/Artemis/Profiles/Layers/Models/LayerPropertiesModel.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.ComponentModel; using System.Windows; using System.Windows.Media; using Artemis.Utilities.Converters; @@ -24,6 +25,7 @@ namespace Artemis.Profiles.Layers.Models Opacity = source.Opacity; AnimationSpeed = source.AnimationSpeed; Conditions = source.Conditions; + ConditionType = source.ConditionType; DynamicProperties = source.DynamicProperties; Brush = source.Brush; HeightEase = source.HeightEase; @@ -47,6 +49,7 @@ namespace Artemis.Profiles.Layers.Models public string WidthEase { set; get; } public string HeightEase { get; set; } public string OpacityEase { get; set; } + public ConditionType ConditionType { get; set; } public List Conditions { get; set; } = new List(); public List DynamicProperties { get; set; } = new List(); @@ -80,4 +83,11 @@ namespace Artemis.Profiles.Layers.Models return new Rect(X*scale, Y*scale, Width*scale, Height*scale); } } + + public enum ConditionType + { + [Description("All met")] AllMet, + [Description("Any met")] AnyMet, + [Description("None met")] NoneMet + } } \ No newline at end of file diff --git a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs index f6a22b203..55b12d98a 100644 --- a/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/Profiles/LayerEditorViewModel.cs @@ -118,7 +118,7 @@ namespace Artemis.ViewModels.Profiles NotifyOfPropertyChange(() => SelectedLayerType); } } - + public void PreSelect() { SelectedLayerType = LayerTypes.FirstOrDefault(t => t.Name == ProposedLayer.LayerType.Name); diff --git a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml index 2beb89dd5..467284257 100644 --- a/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml +++ b/Artemis/Artemis/Views/Flyouts/FlyoutSettingsView.xaml @@ -44,7 +44,6 @@ Style="{StaticResource MahApps.Metro.Styles.ToggleSwitchButton.Win10}" HorizontalAlignment="Right" /> -