mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
Cmdpal: user research on extension invokes (#43905)
## Summary of the Pull Request
Added two events that Niels asked for:
- `CmdPal_ExtensionInvoked`
- Track which extensions are being used (e.g., file search, app
launching, calculator, etc.).
- Properties logged
- ExtensionId - Unique identifier of the extension provider
- CommandType - Display name of the command being invoked
- Success - Whether the command executed successfully
- ExecutionTimeMs - Execution time in milliseconds
- `CmdPal_SessionDuration`
- Tracks how long Command Palette stays open (launch → close).
- Properties logged
- DurationMs - Session duration in milliseconds
- CommandsExecuted - Number of commands executed
- PagesVisited - Number of pages visited
- DismissalReason - Why the session ended (Escape, LostFocus, Command,
etc.)
- SearchQueriesCount - Number of search queries executed
- MaxNavigationDepth - Maximum navigation depth reached
- ErrorCount - Number of errors encountered
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
This commit is contained in:
committed by
GitHub
parent
557a07589d
commit
37bd24db36
@@ -52,6 +52,10 @@ public sealed partial class MainWindow : WindowEx,
|
||||
IRecipient<ShowWindowMessage>,
|
||||
IRecipient<HideWindowMessage>,
|
||||
IRecipient<QuitMessage>,
|
||||
IRecipient<NavigateToPageMessage>,
|
||||
IRecipient<NavigationDepthMessage>,
|
||||
IRecipient<SearchQueryMessage>,
|
||||
IRecipient<ErrorOccurredMessage>,
|
||||
IRecipient<DragStartedMessage>,
|
||||
IRecipient<DragCompletedMessage>,
|
||||
IDisposable
|
||||
@@ -75,6 +79,14 @@ public sealed partial class MainWindow : WindowEx,
|
||||
private bool _ignoreHotKeyWhenFullScreen = true;
|
||||
private bool _themeServiceInitialized;
|
||||
|
||||
// Session tracking for telemetry
|
||||
private Stopwatch? _sessionStopwatch;
|
||||
private int _sessionCommandsExecuted;
|
||||
private int _sessionPagesVisited;
|
||||
private int _sessionSearchQueriesCount;
|
||||
private int _sessionMaxNavigationDepth;
|
||||
private int _sessionErrorCount;
|
||||
|
||||
private DesktopAcrylicController? _acrylicController;
|
||||
private SystemBackdropConfiguration? _configurationSource;
|
||||
private TimeSpan _autoGoHomeInterval = Timeout.InfiniteTimeSpan;
|
||||
@@ -123,6 +135,10 @@ public sealed partial class MainWindow : WindowEx,
|
||||
WeakReferenceMessenger.Default.Register<QuitMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ShowWindowMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<HideWindowMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<NavigateToPageMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<NavigationDepthMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<SearchQueryMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<ErrorOccurredMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<DragStartedMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<DragCompletedMessage>(this);
|
||||
|
||||
@@ -524,6 +540,11 @@ public sealed partial class MainWindow : WindowEx,
|
||||
{
|
||||
var settings = App.Current.Services.GetService<SettingsModel>()!;
|
||||
|
||||
// Start session tracking
|
||||
_sessionStopwatch = Stopwatch.StartNew();
|
||||
_sessionCommandsExecuted = 0;
|
||||
_sessionPagesVisited = 0;
|
||||
|
||||
ShowHwnd(message.Hwnd, settings.SummonOn);
|
||||
}
|
||||
|
||||
@@ -532,6 +553,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
// This might come in off the UI thread. Make sure to hop back.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
EndSession("Hide");
|
||||
HideWindow();
|
||||
});
|
||||
}
|
||||
@@ -551,10 +573,67 @@ public sealed partial class MainWindow : WindowEx,
|
||||
// This might come in off the UI thread. Make sure to hop back.
|
||||
DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
EndSession("Dismiss");
|
||||
HideWindow();
|
||||
});
|
||||
}
|
||||
|
||||
// Session telemetry: Track metrics during the Command Palette session
|
||||
// These receivers increment counters that are sent when EndSession is called
|
||||
public void Receive(NavigateToPageMessage message)
|
||||
{
|
||||
_sessionPagesVisited++;
|
||||
}
|
||||
|
||||
public void Receive(NavigationDepthMessage message)
|
||||
{
|
||||
if (message.Depth > _sessionMaxNavigationDepth)
|
||||
{
|
||||
_sessionMaxNavigationDepth = message.Depth;
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(SearchQueryMessage message)
|
||||
{
|
||||
_sessionSearchQueriesCount++;
|
||||
}
|
||||
|
||||
public void Receive(ErrorOccurredMessage message)
|
||||
{
|
||||
_sessionErrorCount++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ends the current telemetry session and emits the CmdPal_SessionDuration event.
|
||||
/// Aggregates all session metrics collected since ShowWindow and sends them to telemetry.
|
||||
/// </summary>
|
||||
/// <param name="dismissalReason">The reason the session ended (e.g., Dismiss, Hide, LostFocus).</param>
|
||||
private void EndSession(string dismissalReason)
|
||||
{
|
||||
if (_sessionStopwatch is not null)
|
||||
{
|
||||
_sessionStopwatch.Stop();
|
||||
TelemetryForwarder.LogSessionDuration(
|
||||
(ulong)_sessionStopwatch.ElapsedMilliseconds,
|
||||
_sessionCommandsExecuted,
|
||||
_sessionPagesVisited,
|
||||
dismissalReason,
|
||||
_sessionSearchQueriesCount,
|
||||
_sessionMaxNavigationDepth,
|
||||
_sessionErrorCount);
|
||||
_sessionStopwatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments the session commands executed counter for telemetry.
|
||||
/// Called by TelemetryForwarder when an extension command is invoked.
|
||||
/// </summary>
|
||||
internal void IncrementCommandsExecuted()
|
||||
{
|
||||
_sessionCommandsExecuted++;
|
||||
}
|
||||
|
||||
private void HideWindow()
|
||||
{
|
||||
// Cloak our HWND to avoid all animations.
|
||||
@@ -764,6 +843,7 @@ public sealed partial class MainWindow : WindowEx,
|
||||
}
|
||||
|
||||
// This will DWM cloak our window:
|
||||
EndSession("LostFocus");
|
||||
HideWindow();
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnLostFocus());
|
||||
|
||||
Reference in New Issue
Block a user