Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions devel/0156.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# [0156] PDF 标签页支持 Ctrl+W 关闭

## 相关文档
- [dddd.md](dddd.md) - 任务文档模板

## 任务相关的代码文件
- `src/Plugins/Qt/qt_pdf_reader_widget.cpp`
- `src/Plugins/Qt/qt_pdf_reader_widget.hpp`
- `TeXmacs/progs/texmacs/texmacs/tm-server.scm` - `safely-kill-tabpage` 定义

## 如何测试

### 确定性测试(单元测试)
```bash
# 暂无单元测试
```

### 非确定性测试(文档验证)
1. 启动 Mogan,打开一个 PDF 文件
2. 点击 PDF 阅读器区域使其获得焦点
3. 按 Ctrl+W(macOS 上按 Cmd+W)
4. 观察当前 PDF 标签页是否被关闭

## 如何提交

提交前执行以下最少步骤:

```bash
xmake b stem
```

## What

为 PDF 阅读器标签页增加 Ctrl+W(macOS 为 Cmd+W)快捷键关闭支持。

1. 在 `qt_pdf_reader_widget.cpp` 中包含 `scheme.hpp`。
2. 在 `PDFReaderWidget::keyPressEvent` 中捕获 `Ctrl+W` / `Cmd+W` 快捷键。
3. 触发时调用 `eval("(safely-kill-tabpage)")`,由 Scheme 层安全关闭当前标签页。

## Why

目前 PDF 阅读器标签页只能通过点击标签页上的关闭按钮关闭,不支持键盘快捷键。用户在阅读 PDF 时习惯使用 Ctrl+W 快速关闭标签页,缺失该快捷键影响操作效率。

## How

在以下两个位置增加对 `Ctrl+W` / `Cmd+W` 的捕获,确保焦点在阅读器区域或 viewport 上时均能生效:

1. **`PDFReaderWidget::keyPressEvent`**:当焦点在 `PDFReaderWidget` 本身(如 toolbar)时生效。
2. **`PDFReaderWidget::eventFilter`**(监听 `scrollArea_->viewport()`):当焦点在 viewport(即 PDF 内容区域)时生效,这是用户阅读 PDF 时的常见焦点位置。

两处均遵循统一的修饰符判断逻辑:

- 在 Windows/Linux 上检测 `Qt::ControlModifier + Qt::Key_W`。
- 在 macOS 上检测 `Qt::MetaModifier + Qt::Key_W`(Cmd+W),同时兼容 `Qt::ControlModifier`。

匹配到快捷键后,调用 `eval("(safely-kill-tabpage)")`。该 Scheme 函数会自动获取当前窗口和视图,执行关闭标签页的完整逻辑(包括保存确认、视图切换等),与点击关闭按钮行为一致。
23 changes: 23 additions & 0 deletions src/Plugins/Qt/qt_pdf_reader_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "MuPDF/mupdf_renderer.hpp"
#include "qt_dpi_utils.hpp"
#include "qt_utilities.hpp"
#include "scheme.hpp"
#include <mupdf/fitz.h>

#include <mutex>
Expand Down Expand Up @@ -1332,6 +1333,18 @@ PDFReaderWidget::keyPressEvent (QKeyEvent* event) {
}
}

#ifdef Q_OS_MACOS
bool closeModifier= (event->modifiers () & Qt::MetaModifier) ||
(event->modifiers () & Qt::ControlModifier);
#else
bool closeModifier= event->modifiers () & Qt::ControlModifier;
#endif
if (closeModifier && event->key () == Qt::Key_W) {
eval ("(safely-kill-tabpage)");
event->accept ();
return;
}

QWidget::keyPressEvent (event);
}

Expand Down Expand Up @@ -1466,6 +1479,16 @@ PDFReaderWidget::eventFilter (QObject* watched, QEvent* event) {
return true;
}
}
#ifdef Q_OS_MACOS
bool closeModifier= (keyEvent->modifiers () & Qt::MetaModifier) ||
(keyEvent->modifiers () & Qt::ControlModifier);
#else
bool closeModifier= keyEvent->modifiers () & Qt::ControlModifier;
#endif
if (closeModifier && keyEvent->key () == Qt::Key_W) {
eval ("(safely-kill-tabpage)");
return true;
}
}
else if (event->type () == QEvent::Resize) {
if (!pdfData_.isEmpty () && pageCount_ > 0) {
Expand Down
Loading