2023-09-15 08:34:17 +02:00
|
|
|
#include "pch.h"
|
|
|
|
|
#include "bug_report.h"
|
Add progress/result window to the Bug Report flow with a GitHub issue shortcut (#48980)
## Summary of the Pull Request
Adds a small, native progress/result window to the **Bug Report** flow
so users get feedback while the report is generated and a one-click path
to file a GitHub issue.
Previously, triggering "Report bug" (from the tray menu or **Settings →
General**) ran `PowerToys.BugReportTool.exe` hidden for ~30 seconds with
**no feedback at all**, then popped a plain message box. Many users then
had to manually find the `.zip` and figure out where to file the issue.
Now the runner shows a lightweight window that:
- Displays an animated **"Generating bug report…"** state while the tool
runs.
- On completion, shows **where the `.zip` was saved**
(`…\Desktop\PowerToysReport_<timestamp>.zip`) in a read-only, copyable
field.
- Offers **Open folder** (reveals/selects the `.zip` in Explorer) and
**Report on GitHub** (opens the prefilled `bug_report.yml` issue
template *and* reveals the `.zip` so it can be dragged into the issue).
- Shows a clear error state if the report could not be created.
> Note: GitHub has no API/URL to pre-attach a binary to a new issue
(attachments only happen via browser drag-drop). So the "Report on
GitHub" action does the next best thing: opens the prefilled issue page
and highlights the `.zip` in Explorer for a single drag to attach.
https://github.com/user-attachments/assets/9307d728-bbbd-4258-9480-ced65d2fa065
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** Lightweight, additive UX on an existing
feature; happy to adjust per maintainer feedback.
- [ ] **Tests:** No automated tests (native Win32 window in the runner);
validated manually — see below.
- [x] **Localization:** All end-user-facing strings are added to
`src/runner/Resources.resx` and loaded via `GET_RESOURCE_STRING`.
- [ ] **Dev docs:** N/A
- [x] **New binaries:** None — `bug_report_dialog.cpp/.h` compile into
the existing `PowerToys.exe` (runner). No new WinUI app or DLL, so no
signing/WXS/CI changes required.
## Detailed Description of the Pull Request / Additional comments
- New files `src/runner/bug_report_dialog.{h,cpp}` implement the window
as plain Win32 (no Common Controls v6 dependency, no managed/WinUI
payload), so it works for **both** entry points since it lives in the
runner.
- `bug_report.cpp` now calls `run_bug_report_dialog(...)` instead of the
silent run + message box. The "running" state (observed by Settings) is
cleared as soon as the **tool process** exits, so the result window can
stay open without keeping the Settings button spinning. A guard
re-focuses an already-open window instead of starting a second report.
- The window uses the canonical `AttachThreadInput` foreground recipe so
it reliably surfaces even when launched from Settings (a different
foreground process), and gets a taskbar button so it stays findable
during the ~30s run.
- The output path is discovered by locating the newest
`PowerToysReport_*.zip` in the Desktop folder after the tool exits (the
tool names the file internally with a timestamp).
- Strings added: dialog title, generating/hint text, done header/hint,
failed text, and button captions.
## Validation Steps Performed
- Triggered **Report bug** from the **system tray** menu: window appears
in the foreground, animates "Generating…", then shows the saved `.zip`
path with working **Open folder** and **Report on GitHub** buttons.
- Verified **Open folder** selects the `.zip` in Explorer and **Report
on GitHub** opens the prefilled `bug_report.yml` issue template with the
`.zip` highlighted for drag-and-drop.
- Verified the error state renders correctly (and wraps long localized
text) when the tool can't run.
- Built `runner` (ARM64, Debug) clean; verified end-to-end on a high-DPI
display.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-07 10:08:56 +02:00
|
|
|
#include "bug_report_dialog.h"
|
2023-09-15 08:34:17 +02:00
|
|
|
#include "Generated files/resource.h"
|
|
|
|
|
#include <common/utils/process_path.h>
|
|
|
|
|
#include <common/utils/resources.h>
|
|
|
|
|
|
2025-06-17 14:49:54 +08:00
|
|
|
BugReportManager& BugReportManager::instance()
|
|
|
|
|
{
|
|
|
|
|
static BugReportManager instance;
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
2023-09-15 08:34:17 +02:00
|
|
|
|
2025-06-17 14:49:54 +08:00
|
|
|
void BugReportManager::register_callback(const BugReportCallback& callback)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_callbacksMutex);
|
|
|
|
|
m_callbacks.push_back(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BugReportManager::clear_callbacks()
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_callbacksMutex);
|
|
|
|
|
m_callbacks.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BugReportManager::notify_observers(bool isRunning)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_callbacksMutex);
|
|
|
|
|
for (const auto& callback : m_callbacks)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
callback(isRunning);
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
// Ignore callback exceptions to prevent one bad callback from affecting others
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BugReportManager::launch_bug_report() noexcept
|
2023-09-15 08:34:17 +02:00
|
|
|
{
|
|
|
|
|
std::wstring bug_report_path = get_module_folderpath();
|
|
|
|
|
bug_report_path += L"\\Tools\\PowerToys.BugReportTool.exe";
|
|
|
|
|
|
2025-06-17 14:49:54 +08:00
|
|
|
bool expected_isBugReportRunning = false;
|
|
|
|
|
if (m_isBugReportRunning.compare_exchange_strong(expected_isBugReportRunning, true))
|
2023-09-15 08:34:17 +02:00
|
|
|
{
|
2025-06-17 14:49:54 +08:00
|
|
|
// Notify observers that bug report is starting
|
|
|
|
|
notify_observers(true);
|
|
|
|
|
|
|
|
|
|
std::thread([this, bug_report_path]() {
|
Add progress/result window to the Bug Report flow with a GitHub issue shortcut (#48980)
## Summary of the Pull Request
Adds a small, native progress/result window to the **Bug Report** flow
so users get feedback while the report is generated and a one-click path
to file a GitHub issue.
Previously, triggering "Report bug" (from the tray menu or **Settings →
General**) ran `PowerToys.BugReportTool.exe` hidden for ~30 seconds with
**no feedback at all**, then popped a plain message box. Many users then
had to manually find the `.zip` and figure out where to file the issue.
Now the runner shows a lightweight window that:
- Displays an animated **"Generating bug report…"** state while the tool
runs.
- On completion, shows **where the `.zip` was saved**
(`…\Desktop\PowerToysReport_<timestamp>.zip`) in a read-only, copyable
field.
- Offers **Open folder** (reveals/selects the `.zip` in Explorer) and
**Report on GitHub** (opens the prefilled `bug_report.yml` issue
template *and* reveals the `.zip` so it can be dragged into the issue).
- Shows a clear error state if the report could not be created.
> Note: GitHub has no API/URL to pre-attach a binary to a new issue
(attachments only happen via browser drag-drop). So the "Report on
GitHub" action does the next best thing: opens the prefilled issue page
and highlights the `.zip` in Explorer for a single drag to attach.
https://github.com/user-attachments/assets/9307d728-bbbd-4258-9480-ced65d2fa065
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** Lightweight, additive UX on an existing
feature; happy to adjust per maintainer feedback.
- [ ] **Tests:** No automated tests (native Win32 window in the runner);
validated manually — see below.
- [x] **Localization:** All end-user-facing strings are added to
`src/runner/Resources.resx` and loaded via `GET_RESOURCE_STRING`.
- [ ] **Dev docs:** N/A
- [x] **New binaries:** None — `bug_report_dialog.cpp/.h` compile into
the existing `PowerToys.exe` (runner). No new WinUI app or DLL, so no
signing/WXS/CI changes required.
## Detailed Description of the Pull Request / Additional comments
- New files `src/runner/bug_report_dialog.{h,cpp}` implement the window
as plain Win32 (no Common Controls v6 dependency, no managed/WinUI
payload), so it works for **both** entry points since it lives in the
runner.
- `bug_report.cpp` now calls `run_bug_report_dialog(...)` instead of the
silent run + message box. The "running" state (observed by Settings) is
cleared as soon as the **tool process** exits, so the result window can
stay open without keeping the Settings button spinning. A guard
re-focuses an already-open window instead of starting a second report.
- The window uses the canonical `AttachThreadInput` foreground recipe so
it reliably surfaces even when launched from Settings (a different
foreground process), and gets a taskbar button so it stays findable
during the ~30s run.
- The output path is discovered by locating the newest
`PowerToysReport_*.zip` in the Desktop folder after the tool exits (the
tool names the file internally with a timestamp).
- Strings added: dialog title, generating/hint text, done header/hint,
failed text, and button captions.
## Validation Steps Performed
- Triggered **Report bug** from the **system tray** menu: window appears
in the foreground, animates "Generating…", then shows the saved `.zip`
path with working **Open folder** and **Report on GitHub** buttons.
- Verified **Open folder** selects the `.zip` in Explorer and **Report
on GitHub** opens the prefilled `bug_report.yml` issue template with the
`.zip` highlighted for drag-and-drop.
- Verified the error state renders correctly (and wraps long localized
text) when the tool can't run.
- Built `runner` (ARM64, Debug) clean; verified end-to-end on a high-DPI
display.
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-07 10:08:56 +02:00
|
|
|
// Shows the progress/result window and runs the tool. The running
|
|
|
|
|
// state is cleared as soon as the tool process exits, so the window
|
|
|
|
|
// with the result and "Report on GitHub" action can stay open
|
|
|
|
|
// afterwards without keeping the UI in a "running" state.
|
|
|
|
|
run_bug_report_dialog(bug_report_path, [this]() {
|
|
|
|
|
m_isBugReportRunning.store(false);
|
|
|
|
|
notify_observers(false);
|
|
|
|
|
});
|
2023-09-15 08:34:17 +02:00
|
|
|
}).detach();
|
|
|
|
|
}
|
2025-06-17 14:49:54 +08:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
notify_observers(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BugReportManager::is_bug_report_running() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return m_isBugReportRunning.load();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Legacy functions for backward compatibility
|
|
|
|
|
void launch_bug_report() noexcept
|
|
|
|
|
{
|
|
|
|
|
BugReportManager::instance().launch_bug_report();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_bug_report_running() noexcept
|
|
|
|
|
{
|
|
|
|
|
return BugReportManager::instance().is_bug_report_running();
|
2023-09-15 08:34:17 +02:00
|
|
|
}
|