11// Author: Kang Lin <kl222@126.com>
22
3+ #include < QRegularExpression>
34#include < QLoggingCategory>
45#include < QStandardPaths>
56#include < QTemporaryDir>
@@ -113,119 +114,76 @@ bool CDesktopShortcutManager::restoreAllShortcuts()
113114
114115#if defined(Q_OS_LINUX)
115116// GNOME 快捷键管理
117+ // 设置 -> 键盘 -> 键盘快捷键
116118bool CDesktopShortcutManager::disableGNOMEShortcuts ()
117119{
118120 qDebug (log) << " Disable GNOME shortcuts ......" ;
119121
120122 // 备份当前设置
121123 backupGNOMESettings ();
122124
123- // 使用正确的数据结构来存储设置
124- struct GNOMESetting {
125- QString schema;
126- QString key;
127- QString value;
128- };
129-
130- QVector<GNOMESetting> disabledSettings = {
131- // Super 键
132- {" org.gnome.mutter" , " overlay-key" , " ''" },
133-
134- // 窗口管理
135- {" org.gnome.desktop.wm.keybindings" , " close" , " ['']" },
136- {" org.gnome.desktop.wm.keybindings" , " minimize" , " ['']" },
137- {" org.gnome.desktop.wm.keybindings" , " maximize" , " ['']" },
138- {" org.gnome.desktop.wm.keybindings" , " unmaximize" , " ['']" },
139- {" org.gnome.desktop.wm.keybindings" , " begin-move" , " ['']" },
140- {" org.gnome.desktop.wm.keybindings" , " begin-resize" , " ['']" },
141- {" org.gnome.desktop.wm.keybindings" , " toggle-fullscreen" , " ['']" },
142- {" org.gnome.desktop.wm.keybindings" , " toggle-maximized" , " ['']" },
143- {" org.gnome.desktop.wm.keybindings" , " show-desktop" , " ['']" },
144-
145- // 工作区
146- {" org.gnome.desktop.wm.keybindings" , " switch-to-workspace-left" , " ['']" },
147- {" org.gnome.desktop.wm.keybindings" , " switch-to-workspace-right" , " ['']" },
148- {" org.gnome.desktop.wm.keybindings" , " switch-to-workspace-up" , " ['']" },
149- {" org.gnome.desktop.wm.keybindings" , " switch-to-workspace-down" , " ['']" },
150- {" org.gnome.desktop.wm.keybindings" , " switch-to-workspace-last" , " ['']" },
151- {" org.gnome.desktop.wm.keybindings" , " move-to-workspace-left" , " ['']" },
152- {" org.gnome.desktop.wm.keybindings" , " move-to-workspace-right" , " ['']" },
153- {" org.gnome.desktop.wm.keybindings" , " move-to-workspace-up" , " ['']" },
154- {" org.gnome.desktop.wm.keybindings" , " move-to-workspace-down" , " ['']" },
155-
156- {" org.gnome.desktop.wm.keybindings" , " switch-input-source" , " ['']" },
157- {" org.gnome.desktop.wm.keybindings" , " switch-input-source-backward" , " ['']" },
158-
159- // 面板和 Shell
160- {" org.gnome.shell.keybindings" , " toggle-application-view" , " ['']" },
161- {" org.gnome.shell.keybindings" , " toggle-message-tray" , " ['']" },
162- {" org.gnome.shell.keybindings" , " focus-active-notification" , " ['']" },
163- {" org.gnome.shell.keybindings" , " toggle-overview" , " ['']" },
164-
165- {" org.gnome.shell.keybindings" , " screenshot" , " ['']" },
166- {" org.gnome.shell.keybindings" , " screenshot-window" , " ['']" },
167- {" org.gnome.shell.keybindings" , " show-screenshot-ui" , " ['']" },
168- {" org.gnome.shell.keybindings" , " show-screen-recording-ui" , " ['']" },
169-
170- // 媒体键
171- {" org.gnome.settings-daemon.plugins.media-keys" , " home" , " ['']" },
172- {" org.gnome.settings-daemon.plugins.media-keys" , " email" , " ['']" },
173- {" org.gnome.settings-daemon.plugins.media-keys" , " www" , " ['']" },
174- {" org.gnome.settings-daemon.plugins.media-keys" , " calculator" , " ['']" },
175- {" org.gnome.settings-daemon.plugins.media-keys" , " screensaver" , " ['']" },
176- {" org.gnome.settings-daemon.plugins.media-keys" , " media" , " ['']" },
177- {" org.gnome.settings-daemon.plugins.media-keys" , " volume-up" , " ['']" },
178- {" org.gnome.settings-daemon.plugins.media-keys" , " volume-down" , " ['']" },
179- {" org.gnome.settings-daemon.plugins.media-keys" , " volume-mute" , " ['']" },
180- {" org.gnome.settings-daemon.plugins.media-keys" , " next" , " ['']" },
181- {" org.gnome.settings-daemon.plugins.media-keys" , " previous" , " ['']" },
182- {" org.gnome.settings-daemon.plugins.media-keys" , " play" , " ['']" },
183- {" org.gnome.settings-daemon.plugins.media-keys" , " pause" , " ['']" },
184- {" org.gnome.settings-daemon.plugins.media-keys" , " stop" , " ['']" },
185-
186- // 自定义快捷键
187- {" org.gnome.settings-daemon.plugins.media-keys" , " custom-keybindings" , " ['']" },
188-
189- // 其他系统快捷键
190- {" org.gnome.desktop.wm.keybindings" , " panel-main-menu" , " ['']" },
191- {" org.gnome.desktop.wm.keybindings" , " panel-run-dialog" , " ['']" },
192- {" org.gnome.desktop.wm.keybindings" , " switch-applications" , " ['']" },
193- {" org.gnome.desktop.wm.keybindings" , " switch-applications-backward" , " ['']" },
194- {" org.gnome.desktop.wm.keybindings" , " switch-windows" , " ['']" },
195- {" org.gnome.desktop.wm.keybindings" , " switch-windows-backward" , " ['']" },
196- {" org.gnome.desktop.wm.keybindings" , " switch-group" , " ['']" },
197- {" org.gnome.desktop.wm.keybindings" , " switch-group-backward" , " ['']" }
198-
199- };
200-
201- // 应用设置
202- bool allSuccess = true ;
203- int successCount = 0 ;
204- int totalCount = disabledSettings.size ();
205-
206- for (const GNOMESetting &setting : disabledSettings) {
207- if (runCommand (" gsettings" , {" set" , setting.schema , setting.key , setting.value })) {
208- successCount++;
209- qDebug (log) << " Disabled:" << setting.schema << setting.key ;
210- } else {
211- qCritical (log) << " Disable fail:" << setting.schema << setting.key ;
212- allSuccess = false ;
125+ // 禁止设置
126+ bool bAllSuccess = true ;
127+ int nSuccessCount = 0 ;
128+ int nTotalCount = 0 ;
129+ for (auto it = m_gnomeSettings.begin (); it != m_gnomeSettings.end (); ++it) {
130+ QString szSchema = it.key ();
131+ auto keys = it.value ();
132+ for (auto itKey = keys.begin (); itKey != keys.end (); itKey++) {
133+ nTotalCount++;
134+ QString szKey = itKey.key ();
135+ QString szValue = itKey.value ();
136+ // 是否包含 "[]"
137+ // 方法一:直接判断包含 []
138+ // if(!(szValue.contains('[') && szValue.contains(']'))) continue;
139+ // 方法二:使用正则表达式: \[.*\]
140+ if (!szValue.contains (QRegularExpression (" \\ [.*\\ ]" ))) continue ;
141+
142+ // 去掉 [] 中的内容:
143+ /*
144+ * 方法一:正则表达式写法:
145+ *
146+ * (?<=\[)[^\]]*(?=\])
147+ *
148+ * 说明:
149+ * - (?<=\[) — 正向肯定后顾,匹配在 [ 之后的位置
150+ * - [^\]]* — 匹配任意不是 ] 的字符(0个或多个)
151+ * - (?=\]) — 正向肯定前瞻,匹配在 ] 之前的位置
152+ *
153+ * 这样匹配到的就是括号内的内容,不包括括号本身。
154+ * 注意:QRegularExpression 对前瞻/后顾的支持
155+ * Qt 的 QRegularExpression(基于 PCRE)支持前瞻 (?=) 和后顾 (?<=),所以上面的写法是有效的。
156+ */
157+ // szValue = szValue.replace(QRegularExpression("(?<=\\[)[^\\]]*(?=\\])"), "");
158+ /* 方法二:使用捕获组
159+ * 正则表达式:
160+ * \[([^\]]*)\]
161+ * 说明:
162+ * |正则 |C++ 字符串|含义 |
163+ * |-------|---------|-------------------|
164+ * |\[ |"\\[" |匹配左方括号 [ |
165+ * |( |"(" |开始捕获组 |
166+ * |[^\]] |"[^\\]]" |匹配任意不是 ] 的字符 |
167+ * |* |"*" |重复 0 次或多次 |
168+ * |) |")" |结束捕获组 |
169+ * |\] |"\\]" |匹配右方括号 ] |
170+ *
171+ * 注意: [^\\]] 在正则中表示字符类 [^]](匹配非 ] 的字符),但在 C++ 字符串中需要对 \ 和 ] 进行转义。
172+ */
173+ szValue.replace (QRegularExpression (" \\ [([^\\ ]]*)\\ ]" ), " []" );
174+ if (runCommand (" gsettings" , {" set" , szSchema, szKey, szValue})) {
175+ nSuccessCount++;
176+ qDebug (log) << " Disabled:" << szSchema + " : " + szKey + " = " + szValue;
177+ } else {
178+ qCritical (log) << " Disabled failed:" << szSchema + " : " + szKey + " = " + szValue;
179+ bAllSuccess = false ;
180+ }
213181 }
214182 }
215183
216- qDebug (log) << QString (" GNOME is disabled: %1/%2 Success" ).arg (successCount ).arg (totalCount );
184+ qDebug (log) << QString (" GNOME is disabled: %1/%2 Success" ).arg (nSuccessCount ).arg (nTotalCount );
217185
218- /* / 重启 GNOME Shell 使设置生效
219- if (allSuccess || successCount > 0) {
220- qDebug(log) << "Reboot GNOME Shell ......";
221- if (runCommand("killall", {"-3", "gnome-shell"})) {
222- qDebug(log) << "GNOME Shell reboot signal is sended";
223- } else {
224- qWarning(log) << "Reboot GNOME Shell fail, Some settings may require you to log in again to take effect.";
225- }
226- } //*/
227-
228- return allSuccess;
186+ return bAllSuccess;
229187}
230188
231189bool CDesktopShortcutManager::restoreGNOMEShortcuts ()
@@ -237,31 +195,31 @@ bool CDesktopShortcutManager::restoreGNOMEShortcuts()
237195 return false ;
238196 }
239197
240- bool allSuccess = true ;
241- int successCount = 0 ;
242- int totalCount = m_gnomeSettings. size () ;
198+ bool bAllSuccess = true ;
199+ int nSuccessCount = 0 ;
200+ int nTotalCount = 0 ;
243201
244202 // 恢复备份的设置
245203 for (auto it = m_gnomeSettings.begin (); it != m_gnomeSettings.end (); ++it) {
246- QStringList parts = it.key (). split ( " | " );
247- if (parts. size () == 2 ) {
248- QString schema = parts[ 0 ];
249- QString key = parts[ 1 ] ;
250- QString value = it. value (). toString ();
251-
252- if (runCommand (" gsettings" , {" set" , schema, key, value })) {
253- successCount ++;
254- qDebug (log) << " Restored:" << schema << key << value ;
204+ QString szSchema = it.key ();
205+ auto keys = it. value ();
206+ for ( auto itKey = keys. begin (); itKey != keys. end (); itKey++) {
207+ nTotalCount++ ;
208+ QString szKey = itKey. key ();
209+ QString szValue = itKey. value ();
210+ if (runCommand (" gsettings" , {" set" , szSchema, szKey, szValue })) {
211+ nSuccessCount ++;
212+ qDebug (log) << " Restored:" << szSchema + " : " + szKey + " = " + szValue ;
255213 } else {
256- qCritical (log) << " Restore failed:" << schema << key << value ;
257- allSuccess = false ;
214+ qCritical (log) << " Restore failed:" << szSchema + " : " + szKey + " = " + szValue ;
215+ bAllSuccess = false ;
258216 }
259217 }
260218 }
261219
262- qDebug (log) << QString (" GNOME shortcut restoration completed: %1/%2 successful" ).arg (successCount ).arg (totalCount );
220+ qDebug (log) << QString (" GNOME shortcut restoration completed: %1/%2 successful" ).arg (nSuccessCount ).arg (nTotalCount );
263221
264- /* / 重启 GNOME Shell 使设置生效
222+ /* 重启 GNOME Shell 使设置生效。锁屏和注销需要重启才能生效
265223 if (successCount > 0) {
266224 qDebug(log) << "Restart GNOME Shell...";
267225 if (runCommand("killall", {"-3", "gnome-shell"})) {
@@ -271,7 +229,7 @@ bool CDesktopShortcutManager::restoreGNOMEShortcuts()
271229 }
272230 } //*/
273231
274- return allSuccess ;
232+ return bAllSuccess ;
275233}
276234
277235bool CDesktopShortcutManager::resetGNOMEShortcuts ()
@@ -283,30 +241,30 @@ bool CDesktopShortcutManager::resetGNOMEShortcuts()
283241 return false ;
284242 }
285243
286- bool allSuccess = true ;
287- int successCount = 0 ;
288- int totalCount = m_gnomeSettings. size () ;
244+ bool bAllSuccess = true ;
245+ int nSuccessCount = 0 ;
246+ int nTotalCount = 0 ;
289247
290- // 恢复备份的设置
248+ // 重置
291249 for (auto it = m_gnomeSettings.begin (); it != m_gnomeSettings.end (); ++it) {
292- QStringList parts = it.key (). split ( " | " );
293- if (parts. size () == 2 ) {
294- QString schema = parts[ 0 ];
295- QString key = parts[ 1 ] ;
296-
297- if (runCommand (" gsettings" , {" reset" , schema, key })) {
298- successCount ++;
299- qDebug (log) << " Reset:" << schema << key ;
250+ QString szSchema = it.key ();
251+ auto keys = it. value ();
252+ for ( auto itKey = keys. begin (); itKey != keys. end (); itKey++) {
253+ nTotalCount++ ;
254+ QString szKey = itKey. key ();
255+ if (runCommand (" gsettings" , {" reset" , szSchema, szKey })) {
256+ nSuccessCount ++;
257+ qDebug (log) << " Reset:" << szSchema + " : " + szKey ;
300258 } else {
301- qCritical (log) << " Reset failed:" << schema << key ;
302- allSuccess = false ;
259+ qCritical (log) << " Reset failed:" << szSchema + " : " + szKey ;
260+ bAllSuccess = false ;
303261 }
304262 }
305263 }
306264
307- qDebug (log) << QString (" GNOME shortcut reset completed: %1/%2 successful" ).arg (successCount ).arg (totalCount );
265+ qDebug (log) << QString (" GNOME shortcut reset completed: %1/%2 successful" ).arg (nSuccessCount ).arg (nTotalCount );
308266
309- /* / 重启 GNOME Shell 使设置生效
267+ /* 重启 GNOME Shell 使设置生效。锁屏和注销需要重启才能生效
310268 if (successCount > 0) {
311269 qDebug(log) << "Restart GNOME Shell...";
312270 if (runCommand("killall", {"-3", "gnome-shell"})) {
@@ -316,48 +274,50 @@ bool CDesktopShortcutManager::resetGNOMEShortcuts()
316274 }
317275 } //*/
318276
319- return allSuccess ;
277+ return bAllSuccess ;
320278}
321279
322280void CDesktopShortcutManager::backupGNOMESettings ()
323281{
324282 qDebug (log) << " Backup GNOME settings ......" ;
283+ int nTotalCount = 0 ;
284+ QString szDesktop = " ." + m_desktopEnv.toLower () + " ." ;
325285
326286 m_gnomeSettings.clear ();
327287
328- // 重要的 GNOME 设置 schema
329- QVector<QString> schemas = {
330- " org.gnome.desktop.wm.keybindings" ,
331- " org.gnome.shell.keybindings" ,
332- " org.gnome.settings-daemon.plugins.media-keys" ,
333- " org.gnome.mutter"
334- };
335-
336- for (const QString &schema : schemas) {
288+ // 可以使用下面命令得到 schema
289+ // `gsettings list-schemas|grep keybindings|grep org.gnome.`
290+ QString szSchemas = getCommandOutput (" gsettings" , {" list-schemas" });
291+ // qDebug(log) << "Schemas:\n" << szSchemas;
292+ QStringList lstSchemas = szSchemas.split (' \n ' , Qt::SkipEmptyParts);
293+ foreach (const QString &schema, lstSchemas) {
294+ if (!schema.contains (" keybindings" )) continue ;
295+ // if(!schema.contains(szDesktop)) continue;
337296 // 获取 schema 的所有键
338297 QString output = getCommandOutput (" gsettings" , {" list-keys" , schema});
339298 if (output.isEmpty ()) {
340299 qWarning (log) << " Unable to retrieve the schema key:" << schema;
341300 continue ;
342301 }
343302
303+ QMap<QString, QString> vKey;
344304 QStringList keys = output.split (' \n ' , Qt::SkipEmptyParts);
345305 qDebug (log) << QString (" Schema %1 has %2 keys" ).arg (schema).arg (keys.size ());
346-
347306 foreach (const QString &key, keys) {
348307 QString value = getCommandOutput (" gsettings" , {" get" , schema, key}).trimmed ();
349308 if (!value.isEmpty ()) {
350- // 使用 schema + key 作为唯一标识
351- QString settingKey = schema + " |" + key;
352- m_gnomeSettings[settingKey] = value;
353- qDebug (log) << " Backup:" << settingKey << " =" << value;
309+ nTotalCount++;
310+ vKey.insert (key, value);
311+ qDebug (log) << " Backup:" << schema + " : " + key << " =" << value;
354312 } else {
355- qWarning (log) << " Backup fail:" << schema + " | " + key;
313+ qWarning (log) << " Backup fail:" << schema + " : " + key;
356314 }
357315 }
316+ if (!vKey.isEmpty ())
317+ m_gnomeSettings.insert (schema, vKey);
358318 }
359319
360- qDebug (log) << QString (" GNOME settings backup completed, a total of %1 settings were backed up" ).arg (m_gnomeSettings. size () );
320+ qDebug (log) << QString (" GNOME settings backup completed, a total of %1 settings were backed up" ).arg (nTotalCount );
361321}
362322
363323// KDE 快捷键管理
0 commit comments