Skip to content

Commit 0e1e108

Browse files
committed
feat: implement window split mode with dynamic title display
1. Add window split mode to display individual windows separately in taskbar 2. Implement dynamic title calculation with adaptive character limits based on available space 3. Add new AppItemWithTitle component that displays window titles alongside icons 4. Enhance drag and drop functionality to support individual window dragging 5. Update context menu to show "Close" instead of "Close All" in split mode 6. Add WinTitleRole support in model for window title data 7. Implement intelligent window grouping logic to keep windows of same app together Log: Added window split mode showing individual window titles in taskbar Influence: 1. Test window split mode activation and deactivation 2. Verify window titles display correctly with dynamic character limits 3. Test drag and drop of individual windows in split mode 4. Check context menu shows appropriate close options 5. Verify window grouping maintains proper order 6. Test window activation and new instance creation 7. Validate title truncation and ellipsis behavior 8. Test with multiple windows of same application feat: 实现窗口分离模式并支持动态标题显示 1. 添加窗口分离模式,在任务栏中分别显示各个窗口 2. 实现基于可用空间的动态字符限制计算 3. 新增 AppItemWithTitle 组件,在图标旁显示窗口标题 4. 增强拖放功能以支持单独窗口拖动 5. 更新上下文菜单,在分离模式下显示"关闭"而非"全部关闭" 6. 在模型中添加 WinTitleRole 支持窗口标题数据 7. 实现智能窗口分组逻辑,保持同一应用的窗口在一起 Log: 新增窗口分离模式,在任务栏显示单独窗口标题 整体计算方式为: 获取任务栏的剩余范围remainingSpacesForSplitWindow,默认给所有应用窗口标题为最大宽度--7个汉字的宽度, 然后判断所有应用窗口的图标+标题总和宽度是否大于remainingSpacesForSplitWindow, 如果大于就开始缩减此时窗口的标签中最长标题的长度,(charLimits具体就是存着相对应的index存着字符的数量。)
1 parent 33f2d93 commit 0e1e108

File tree

5 files changed

+914
-36
lines changed

5 files changed

+914
-36
lines changed

panels/dock/taskmanager/dockglobalelementmodel.cpp

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,55 @@ DockGlobalElementModel::DockGlobalElementModel(QAbstractItemModel *appsModel, Do
6464
auto index = m_activeAppModel->index(i, 0);
6565
auto desktopId = index.data(TaskManager::DesktopIdRole).toString();
6666

67-
auto it = std::find_if(m_data.begin(), m_data.end(), [this, &desktopId](auto &data) {
68-
return m_appsModel == std::get<1>(data) && desktopId == std::get<0>(data);
67+
if (desktopId.isEmpty())
68+
continue;
69+
//将同一应用的窗口添加到一起
70+
// Find the first occurrence of this app in m_data (either docked item or existing window)
71+
auto firstIt = std::find_if(m_data.begin(), m_data.end(), [&desktopId](const auto &data) {
72+
return std::get<0>(data) == desktopId;
6973
});
7074

71-
if (it != m_data.end()) {
72-
*it = std::make_tuple(desktopId, m_activeAppModel, i);
73-
auto pIndex = this->index(it - m_data.begin(), 0);
74-
Q_EMIT dataChanged(pIndex, pIndex, {TaskManager::ActiveRole, TaskManager::AttentionRole, TaskManager::WindowsRole, TaskManager::MenusRole});
75-
76-
} else {
75+
if (firstIt == m_data.end()) {
76+
// No docked item or existing window yet, append to the end
7777
beginInsertRows(QModelIndex(), m_data.size(), m_data.size());
7878
m_data.append(std::make_tuple(desktopId, m_activeAppModel, i));
7979
endInsertRows();
80+
continue;
8081
}
82+
83+
// If the first occurrence still comes from m_appsModel, this is the first window:
84+
// reuse the docked position and turn it into a running window.
85+
if (std::get<1>(*firstIt) == m_appsModel) {
86+
*firstIt = std::make_tuple(desktopId, m_activeAppModel, i);
87+
auto pIndex = this->index(firstIt - m_data.begin(), 0);
88+
Q_EMIT dataChanged(pIndex,
89+
pIndex,
90+
{TaskManager::ActiveRole,
91+
TaskManager::AttentionRole,
92+
TaskManager::WindowsRole,
93+
TaskManager::MenusRole,
94+
TaskManager::WinTitleRole});
95+
continue;
96+
}
97+
98+
// There are already windows for this app: insert the new window
99+
// right after the last existing one so that all windows stay together.
100+
auto lastIt = firstIt;
101+
while (lastIt + 1 != m_data.end() && std::get<0>(*(lastIt + 1)) == desktopId) {
102+
++lastIt;
103+
}
104+
105+
auto insertRow = (lastIt - m_data.begin()) + 1;
106+
beginInsertRows(QModelIndex(), insertRow, insertRow);
107+
m_data.insert(lastIt + 1, std::make_tuple(desktopId, m_activeAppModel, i));
108+
endInsertRows();
81109
}
82110

83111
std::for_each(m_data.begin(), m_data.end(), [this, first, last](auto &data) {
84112
if (std::get<1>(data) == m_activeAppModel && std::get<2>(data) > first) {
85-
data = std::make_tuple(std::get<0>(data), std::get<1>(data), std::get<2>(data) + ((last - first) + 1));
113+
data = std::make_tuple(std::get<0>(data),
114+
std::get<1>(data),
115+
std::get<2>(data) + ((last - first) + 1));
86116
}
87117
});
88118
},
@@ -123,7 +153,7 @@ DockGlobalElementModel::DockGlobalElementModel(QAbstractItemModel *appsModel, Do
123153
*it = std::make_tuple(id, m_appsModel, row);
124154
Q_EMIT dataChanged(pIndex,
125155
pIndex,
126-
{TaskManager::ActiveRole, TaskManager::AttentionRole, TaskManager::WindowsRole, TaskManager::MenusRole});
156+
{TaskManager::ActiveRole, TaskManager::AttentionRole, TaskManager::WindowsRole, TaskManager::MenusRole, TaskManager::WinTitleRole});
127157
}
128158
} else {
129159
beginRemoveRows(QModelIndex(), pos, pos);
@@ -303,7 +333,11 @@ QString DockGlobalElementModel::getMenus(const QModelIndex &index) const
303333
if (TaskManagerSettings::instance()->isAllowedForceQuit()) {
304334
menusArray.append(QJsonObject{{"id", DOCK_ACTION_FORCEQUIT}, {"name", tr("Force Quit")}});
305335
}
306-
menusArray.append(QJsonObject{{"id", DOCK_ACTION_CLOSEALL}, {"name", tr("Close All")}});
336+
if (TaskManagerSettings::instance()->isWindowSplit()) {
337+
menusArray.append(QJsonObject{{"id", DOCK_ACTION_CLOSEWINDOW}, {"name", tr("Close")}});
338+
} else {
339+
menusArray.append(QJsonObject{{"id", DOCK_ACTION_CLOSEALL}, {"name", tr("Close All")}});
340+
}
307341
}
308342

309343
return QJsonDocument(menusArray).toJson();
@@ -366,6 +400,49 @@ void DockGlobalElementModel::requestActivate(const QModelIndex &index) const
366400
}
367401
}
368402

403+
void DockGlobalElementModel::requestNewInstance(const QModelIndex &index, const QString &action) const
404+
{
405+
auto data = m_data.value(index.row());
406+
auto id = std::get<0>(data);
407+
auto sourceModel = std::get<1>(data);
408+
auto sourceRow = std::get<2>(data);
409+
410+
// Handle special actions first (for both active and docked apps)
411+
if (action == DOCK_ACTION_DOCK) {
412+
TaskManagerSettings::instance()->toggleDockedElement(QStringLiteral("desktop/%1").arg(id));
413+
return;
414+
} else if (action == DOCK_ACTION_FORCEQUIT) {
415+
requestClose(index, true);
416+
return;
417+
} else if (action == DOCK_ACTION_CLOSEWINDOW || action == DOCK_ACTION_CLOSEALL) {
418+
requestClose(index, false);
419+
return;
420+
}
421+
422+
//应用自身处理的action
423+
if (!action.isEmpty()) {
424+
QProcess process;
425+
process.setProcessChannelMode(QProcess::MergedChannels);
426+
process.start("dde-am", {"--by-user", id, action});
427+
process.waitForFinished();
428+
return;
429+
}
430+
431+
// Handle launch/activate (empty action)
432+
if (sourceModel == m_activeAppModel) {
433+
auto sourceIndex = sourceModel->index(sourceRow, 0);
434+
m_activeAppModel->requestNewInstance(sourceIndex, action);
435+
} else {
436+
QString dbusPath = QStringLiteral("/org/desktopspec/ApplicationManager1/") + escapeToObjectPath(id);
437+
using Application = org::desktopspec::ApplicationManager1::Application;
438+
Application appInterface(QStringLiteral("org.desktopspec.ApplicationManager1"), dbusPath, QDBusConnection::sessionBus());
439+
440+
if (appInterface.isValid()) {
441+
appInterface.Launch(QString(), QStringList(), QVariantMap());
442+
}
443+
}
444+
}
445+
369446
void DockGlobalElementModel::requestOpenUrls(const QModelIndex &index, const QList<QUrl> &urls) const
370447
{
371448
auto data = m_data.value(index.row());

panels/dock/taskmanager/dockglobalelementmodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class DockGlobalElementModel : public QAbstractListModel, public AbstractTaskMan
2828
inline int mapToSourceModelRole(QAbstractItemModel *model, int role) const;
2929

3030
void requestActivate(const QModelIndex &index) const override;
31+
void requestNewInstance(const QModelIndex &index, const QString &action) const override;
3132

3233
void requestOpenUrls(const QModelIndex &index, const QList<QUrl> &urls) const override;
3334
void requestClose(const QModelIndex &index, bool force = false) const override;

panels/dock/taskmanager/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace dock {
1313
static inline const QString DOCK_ACTION_ALLWINDOW = "dock-action-allWindow";
1414
static inline const QString DOCK_ACTION_FORCEQUIT = "dock-action-forceQuit";
1515
static inline const QString DOCK_ACTION_CLOSEALL = "dock-action-closeAll";
16+
static inline const QString DOCK_ACTION_CLOSEWINDOW = "dock-action-closeWindow";
1617
static inline const QString DOCK_ACTIN_LAUNCH = "dock-action-launch";
1718
static inline const QString DOCK_ACTION_DOCK = "dock-action-dock";
1819

0 commit comments

Comments
 (0)