diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsCache.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsCache.cs index 3e2d73aa8..a4eba2799 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsCache.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsCache.cs @@ -48,7 +48,7 @@ internal class TabsCache var key = RuntimeIdToKey(tab); if (key != null) { - Context.API.LogDebug(ClassName, $"Adding a tab to cache: {tab.Current.Name}"); + Context.API.LogDebug(ClassName, $"TABS:{key}:Adding to cache: {tab.Current.Name}"); _knownTabs.Add(key); } } @@ -87,14 +87,9 @@ internal class TabsCache var existingKeys = existingTabs.Select(RuntimeIdToKey).Where(k => k != null).ToHashSet(); var keysToRemove = _knownTabs.Where(t => t.StartsWith(rootKey) && !existingKeys.Contains(t)); - //Context.API.LogDebug(ClassName, $"Rootkey: {rootKey}"); - //Context.API.LogDebug(ClassName, $"Existing keys:\r\n{string.Join("\r\n", existingKeys)}"); - //Context.API.LogDebug(ClassName, $"Known Tabs:\r\n{string.Join("\r\n", _knownTabs)}"); - //Context.API.LogDebug(ClassName, $"Tabs to remove:\r\n{string.Join("\r\n", keysToRemove)}"); - foreach (var key in keysToRemove) { - Context.API.LogDebug(ClassName, $"Removing a tab from cache: {key}"); + Context.API.LogDebug(ClassName, $"TABS:{key}:Removing from cache"); _knownTabs.Remove(key); } } diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsDebug.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsDebug.cs index 25809a5c6..30bdfa6a1 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsDebug.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsDebug.cs @@ -12,8 +12,16 @@ internal class TabsDebug { private static readonly string ClassName = nameof(TabsDebug); + public static void DumpTabs(AutomationElement parent) + { + DumpElements(parent, null, "Tab"); + } + public static void DumpElements(AutomationElement parent, string classNameOnly = null, string controlTypeOnly = null, int indent = 0) { + if (parent == null) + return; + AutomationElementCollection children; try { @@ -21,7 +29,7 @@ internal class TabsDebug } catch (ElementNotAvailableException ex) { - Context.API.LogDebug(ClassName, $"Parent not available: {ex.Message}"); + Context.API.LogDebug(ClassName, $"TABS:Parent not available: {ex.Message}"); return; } @@ -48,7 +56,7 @@ internal class TabsDebug { Context.API.LogDebug( ClassName, - $"{new string(' ', indent)}" + + $"TABS:{new string(' ', indent)}" + $"Type='{type}', " + $"ClassName='{className}', " + $"Name='{name}', " + @@ -62,11 +70,11 @@ internal class TabsDebug } catch (ElementNotAvailableException ex) { - Context.API.LogDebug(ClassName, $"Child not available: {ex.Message}"); + Context.API.LogDebug(ClassName, $"TABS:Child not available: {ex.Message}"); } catch (Exception ex) { - Context.API.LogException(ClassName, $"Unexpected error", ex); + Context.API.LogException(ClassName, $"TABS:Unexpected error", ex); } } } diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsFocusEventDispatcher.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsFocusEventDispatcher.cs index 9b3117130..78c82c922 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsFocusEventDispatcher.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsFocusEventDispatcher.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Diagnostics; using System.Threading; using System.Windows.Automation; +using System.Windows.Input; using Flow.Launcher.Plugin.BrowserBookmark.Tabs; using static Flow.Launcher.Plugin.BrowserBookmark.Main; @@ -70,11 +71,11 @@ internal sealed class TabsFocusEventDispatcher : IDisposable } catch (ArgumentException) { - Context.API.LogError(ClassName, $"Process {processId} no longer runs"); + Context.API.LogError(ClassName, $"TABS:Process {processId} no longer runs"); } catch (Exception ex) { - Context.API.LogException(ClassName, "Exception", ex); + Context.API.LogException(ClassName, "TABS:Exception", ex); } } diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsTracker.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsTracker.cs index 300770737..a8f67ba8d 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsTracker.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsTracker.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; using System.Windows.Automation; +using System.Windows.Forms; +using System.Windows.Input; using BrowserTabs; using Flow.Launcher.Plugin.BrowserBookmark.Models; using static Flow.Launcher.Plugin.BrowserBookmark.Main; @@ -37,7 +39,6 @@ public class TabsTracker : IDisposable { if (settings.ReuseTabs) { - Context.API.LogDebug(ClassName, $"Opening... {url}"); ExpectUrl(url); } Context.API.OpenUrl(url); @@ -55,14 +56,12 @@ public class TabsTracker : IDisposable var existingTab = GetExistingTab(bookmarkUrl); if (existingTab != null) { - Context.API.LogDebug(ClassName, $"Mapped {bookmarkUrl}"); - r.ContextData = existingTab; r.Action = c => { if (!existingTab.ActivateTab()) { - Context.API.LogError(ClassName, "Failed to activate a tab"); + Context.API.LogError(ClassName, $"TABS:{TabsCache.RuntimeIdToKey(existingTab.AutomationElement)}:Failed to activate"); Remove(bookmarkUrl); OpenUrlAndTrack(settings, bookmarkUrl); } @@ -163,14 +162,12 @@ public class TabsTracker : IDisposable if (!chromium && !firefox) return; // not a browser - Context.API.LogDebug(ClassName, $"The active browser is {process.ProcessName}"); + Context.API.LogDebug(ClassName, $"TABS:The active browser is {process.ProcessName}"); var rootElement = AutomationElement.FromHandle(process.MainWindowHandle); if (rootElement == null) return; - Context.API.LogDebug(ClassName, $"The root element is {rootElement.Current.Name}"); - string? urlToBind; lock (_sync) { @@ -182,14 +179,14 @@ public class TabsTracker : IDisposable if (urlToBind is null) return; - Context.API.LogDebug(ClassName, $"Searching for... {urlToBind}"); + Context.API.LogDebug(ClassName, $"TABS:Searching for... {urlToBind}"); // Further handling requires waiting for tabs so its better to run it on a separate thread _focusHandlerDispatcher?.Enqueue(urlToBind, rootElement, pid); } catch (Exception ex) { - Context.API.LogException(ClassName, "Exception", ex); + Context.API.LogException(ClassName, "TABS:Exception", ex); } } @@ -204,17 +201,20 @@ public class TabsTracker : IDisposable // TODO: Consider ChildAdded to handle new tabs appearance instead of AutomationFocusChangedEventHandler // However think twice if it is worthwhile as the current approach based on focus might already be a good one //case StructureChangeType.ChildAdded: - // Context.API.LogDebug(ClassName, $"StructureChangeType.ChildAdded occurred on {eventRuntimeId}"); + // Context.API.LogDebug(ClassName, $"TABS:StructureChangeType.ChildAdded occurred on {sender} for {eventRuntimeId}"); // break; //case StructureChangeType.ChildrenBulkAdded: - // Context.API.LogDebug(ClassName, $"StructureChangeType.ChildrenBulkAdded occurred on {eventRuntimeId}"); + // Context.API.LogDebug(ClassName, $"TABS:StructureChangeType.ChildrenBulkAdded occurred on {sender} for {eventRuntimeId}"); // break; //case StructureChangeType.ChildrenInvalidated: + // Context.API.LogDebug(ClassName, $"TABS:StructureChangeType.ChildrenInvalidated occurred on {sender} for {eventRuntimeId}"); // _walker.CheckTabExistence(eventRuntimeId, "StructureChangeType.ChildrenInvalidated"); // break; //case StructureChangeType.ChildrenReordered: + // Context.API.LogDebug(ClassName, $"TABS:StructureChangeType.ChildrenReordered occurred on {sender} for {eventRuntimeId}"); // _walker.CheckTabExistence(eventRuntimeId, "StructureChangeType.ChildrenReordered"); // break; + case StructureChangeType.ChildRemoved: case StructureChangeType.ChildrenBulkRemoved: AutomationElement? foundWindow = null; @@ -255,7 +255,7 @@ public class TabsTracker : IDisposable } if (contains) { - Context.API.LogDebug(ClassName, "Unsubscribe window from StructureChanged events"); + Context.API.LogDebug(ClassName, "TABS:Unsubscribe window from StructureChanged events"); Automation.RemoveStructureChangedEventHandler(wnd, OnStructureChanged); _walker?.RemoveAllTabs(wnd); } @@ -265,7 +265,7 @@ public class TabsTracker : IDisposable { lock (_sync) { - Context.API.LogDebug(ClassName, $"Registering {url} as tab: {currentTab.Title}"); + Context.API.LogDebug(ClassName, $"TABS:{TabsCache.RuntimeIdToKey(currentTab.AutomationElement)}:Registering {url} as tab: {currentTab.Title}"); UrlToBrowserTab[url] = currentTab; // required to take the tab into account by Flow Launcher main UI search window diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsWalker.cs b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsWalker.cs index 6b1060e78..90a3a7510 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsWalker.cs +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Tabs/TabsWalker.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Windows.Automation; +using System.Windows.Forms; +using System.Windows.Input; using BrowserTabs; using static Flow.Launcher.Plugin.BrowserBookmark.Main; @@ -36,7 +38,7 @@ internal class TabsWalker var className = tab.Current.ClassName; if (className.Contains("bolt-tab", StringComparison.OrdinalIgnoreCase)) { - Context.API.LogDebug(ClassName, $"Skipping name='{name}', className='{className}'"); + Context.API.LogDebug(ClassName, $"TABS:Skipping name='{name}', className='{className}'"); continue; } @@ -64,19 +66,19 @@ internal class TabsWalker while (sw.Elapsed < _tabRetryTimeout && !cancellationToken.IsCancellationRequested) { - Context.API.LogDebug(ClassName, $"Start searching for a new tab... Try no {count++}"); + Context.API.LogDebug(ClassName, $"TABS:Start searching for a new tab... Try no {count++}"); var tabs = FindAllValidTabs(mainWindow).ToList(); if (tabs.Count == 0) { - Context.API.LogDebug(ClassName, "No valid tabs found"); + Context.API.LogDebug(ClassName, "TABS:No valid tabs found"); Thread.Sleep(_tabRetryInterval); continue; } if (_cache.Empty()) { - Context.API.LogDebug(ClassName, "First time filling the cache"); + Context.API.LogDebug(ClassName, "TABS:First time filling the cache"); _cache.Add(tabs); // Let's take the last one and assume this is the one that was created recently @@ -86,8 +88,8 @@ internal class TabsWalker return InitiateTab(process, tabs.Last()); } - Context.API.LogDebug(ClassName, $"Found tabs: {tabs.Count}"); - //TabsDebug.DumpElements(mainWindow, null, "Tab"); + Context.API.LogDebug(ClassName, $"TABS:Found tabs: {tabs.Count}"); + //TabsDebug.DumpTabs(mainWindow); // searching from the end and looking for a tab not in the cache for (var i = tabs.Count - 1; i >= 0; i--) @@ -95,38 +97,38 @@ internal class TabsWalker var tab = tabs[i]; if (!_cache.Contains(tab)) { - Context.API.LogDebug(ClassName, $"FOUND A NEW TAB: name={tab.Current.Name}, className={tab.Current.ClassName}"); + Context.API.LogDebug(ClassName, $"TABS:FOUND A NEW TAB: name={tab.Current.Name}, className={tab.Current.ClassName}"); _cache.Add(tab); return InitiateTab(process, tab); } } - Context.API.LogDebug(ClassName, "No new tab found"); + Context.API.LogDebug(ClassName, "TABS:No new tab found"); Thread.Sleep(_tabRetryInterval); } - Context.API.LogDebug(ClassName, "Timeout waiting for new tab"); + Context.API.LogDebug(ClassName, "TABS:Timeout waiting for new tab"); } catch (ElementNotAvailableException ex) { - Context.API.LogException(ClassName, "Element not available", ex); + Context.API.LogException(ClassName, "TABS:Element not available", ex); } catch (Exception ex) { - Context.API.LogException(ClassName, "Error getting current tab from window", ex); + Context.API.LogException(ClassName, "TABS:Error getting current tab from window", ex); } return null; } internal void RescanTabsForContainer(AutomationElement browserWindow) { - Context.API.LogDebug(ClassName, "Rescanning tabs in order to find removed tabs"); + Context.API.LogDebug(ClassName, "TABS:Rescanning tabs in order to find removed tabs"); _cache.RemoveAllNonExistentTabs(browserWindow, FindAllValidTabs(browserWindow)); } internal void RemoveAllTabs(AutomationElement browserWindow) { - Context.API.LogDebug(ClassName, "Removing all tabs in a window"); + Context.API.LogDebug(ClassName, "TABS:Removing all tabs in a window"); _cache.RemoveAllNonExistentTabs(browserWindow, []); } @@ -134,7 +136,7 @@ internal class TabsWalker { if (_cache.Contains(runtimeId)) { - Context.API.LogDebug(ClassName, $"Tab exists {reason}"); + Context.API.LogDebug(ClassName, $"TABS:{runtimeId}:Tab exists {reason}"); } } }