diff options
author | Mavridis Philippe <mavridisf@gmail.com> | 2024-10-28 14:40:20 +0200 |
---|---|---|
committer | Mavridis Philippe <mavridisf@gmail.com> | 2024-11-12 22:29:51 +0200 |
commit | 71068b3b258a340be30a91c3a5af92718da70cdd (patch) | |
tree | 6ba4afb1b1b254f21cef141321a51b5605ba54c4 /kxkb/kxkb.cpp | |
parent | 1afb78e598cc0d8c320e98c963cb98ab7935435f (diff) | |
download | tdebase-71068b3b258a340be30a91c3a5af92718da70cdd.tar.gz tdebase-71068b3b258a340be30a91c3a5af92718da70cdd.zip |
Kxkb: improve system tray code and fix various switching-related bugs
- Improved layout change logic (indicator is now always updated when the actual switch occurs). This fixes layout switching triggered by the X11 shortcut not being synchronized with layout switching from the tray icon click and the TDE shortcut.
- Kxkb will ignore XkbStateNotify events not related to XkbGroupState which caused strange behaviour with the system tray context menu.
- Merged KxkbLabelController into KxkbSystemTray
This resolves #547.
Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
Diffstat (limited to 'kxkb/kxkb.cpp')
-rw-r--r-- | kxkb/kxkb.cpp | 258 |
1 files changed, 129 insertions, 129 deletions
diff --git a/kxkb/kxkb.cpp b/kxkb/kxkb.cpp index 1d899299f..bbfa4d87e 100644 --- a/kxkb/kxkb.cpp +++ b/kxkb/kxkb.cpp @@ -86,7 +86,6 @@ KXKBApp::KXKBApp(bool allowStyles, bool GUIenabled) addKipcEventMask( KIPC::SettingsChanged ); } - KXKBApp::~KXKBApp() { delete m_tray; @@ -100,9 +99,8 @@ KXKBApp::~KXKBApp() int KXKBApp::newInstance() { if (settingsRead()) { - layoutApply(); + setLayout(m_currentLayout); } - return 0; } @@ -117,9 +115,9 @@ bool KXKBApp::settingsRead() kapp->quit(); return false; } - + m_prevWinId = X11Helper::UNKNOWN_WINDOW_ID; - + if( kxkbConfig.m_switchingPolicy == SWITCH_POLICY_GLOBAL ) { delete kWinModule; kWinModule = NULL; @@ -130,7 +128,7 @@ bool KXKBApp::settingsRead() kdWarning() << "With non-virtual desktop only global switching policy supported on non-primary screens" << endl; //TODO: find out how to handle that } - + if( kWinModule == NULL ) { kWinModule = new KWinModule(0, KWinModule::INFO_DESKTOP); connect(kWinModule, TQ_SIGNAL(activeWindowChanged(WId)), TQ_SLOT(windowChanged(WId))); @@ -138,27 +136,27 @@ bool KXKBApp::settingsRead() m_prevWinId = kWinModule->activeWindow(); kdDebug() << "Active window " << m_prevWinId << endl; } - + m_layoutOwnerMap->reset(); m_layoutOwnerMap->setCurrentWindow( m_prevWinId ); if( m_rules == NULL ) m_rules = new XkbRules(false); - + for(int ii=0; ii<(int)kxkbConfig.m_layouts.count(); ii++) { LayoutUnit& layoutUnit = kxkbConfig.m_layouts[ii]; } - + m_currentLayout = kxkbConfig.m_layouts[0]; kdDebug() << "default layout is " << m_currentLayout.toPair() << endl; - + if( kxkbConfig.m_layouts.count() == 1 && !kxkbConfig.m_showSingle) { kapp->quit(); return false; } initTray(); - + TDEGlobal::config()->reparseConfiguration(); // kcontrol modified kdeglobals keys->readSettings(); keys->updateConnections(); @@ -168,162 +166,164 @@ bool KXKBApp::settingsRead() void KXKBApp::initTray() { - if( !m_tray ) - { - KSystemTray* sysTray = new KxkbSystemTray(); - TDEPopupMenu* popupMenu = sysTray->contextMenu(); - // popupMenu->insertTitle( kapp->miniIcon(), kapp->caption() ); - - m_tray = new KxkbLabelController(sysTray, popupMenu); - connect(popupMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(menuActivated(int))); - connect(sysTray, TQ_SIGNAL(toggled()), this, TQ_SLOT(nextLayout())); - } - - m_tray->setShowFlag(kxkbConfig.m_showFlag); - m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules); - m_tray->setCurrentLayout(m_currentLayout); - m_tray->show(); -} + if (!m_tray) + { + m_tray = new KxkbSystemTray(); + connect(m_tray, TQ_SIGNAL(menuActivated(int)), this, TQ_SLOT(menuActivated(int))); + connect(m_tray, TQ_SIGNAL(toggled()), this, TQ_SLOT(nextLayout())); + } -// This function activates the keyboard layout specified by the -// configuration members (m_currentLayout) -void KXKBApp::layoutApply() -{ - setLayout(m_currentLayout); + m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules); + m_tray->setCurrentLayout(m_currentLayout); + m_tray->show(); } // kdcop bool KXKBApp::setLayout(const TQString& layoutPair) { - const LayoutUnit layoutUnitKey(layoutPair); - if( kxkbConfig.m_layouts.contains(layoutUnitKey) ) { - return setLayout( *kxkbConfig.m_layouts.find(layoutUnitKey) ); - } - return false; + return setLayout((LayoutUnit)layoutPair); } // Activates the keyboard layout specified by 'layoutUnit' bool KXKBApp::setLayout(const LayoutUnit& layoutUnit) { - uint group = kxkbConfig.m_layouts.findIndex(layoutUnit); - bool res = m_extension->setGroup(group); - if (res) { - m_currentLayout = layoutUnit; - maybeShowLayoutNotification(); - } - - if (m_tray) { - if (res) { - m_tray->setCurrentLayout(layoutUnit); - } else { - m_tray->setError(layoutUnit.toPair()); - } - } - - return res; + const int group = kxkbConfig.m_layouts.findIndex(layoutUnit); + if (group >= 0) { + return setLayout(group); + } + return false; } + // Activates the keyboard layout specified by group number bool KXKBApp::setLayout(const uint group) { - bool res = m_extension->setGroup(group); - if (res) { - m_currentLayout = kxkbConfig.m_layouts[group]; - } + // If this group is already set, just show the notification and return + if (m_extension->getGroup() == group) { + if (kxkbConfig.m_enableNotify) { + showLayoutNotification(); + } + return true; + } - if (m_tray) { - if (res) - m_tray->setCurrentLayout(m_currentLayout); - else - m_tray->setError(m_currentLayout.toPair()); - } + bool ok = m_extension->setGroup(group); + if (!ok) { + TQString layout = kxkbConfig.m_layouts[group].toPair(); + if (m_tray) { + m_tray->setError(layout); + } - return res; + if (kxkbConfig.m_enableNotify) { + showErrorNotification(layout); + } + } + return ok; } - void KXKBApp::nextLayout() { - const LayoutUnit& layout = m_layoutOwnerMap->getNextLayout().layoutUnit; - setLayout(layout); + const LayoutUnit& layout = m_layoutOwnerMap->getNextLayout().layoutUnit; + setLayout(layout); } void KXKBApp::prevLayout() { - const LayoutUnit& layout = m_layoutOwnerMap->getPrevLayout().layoutUnit; - setLayout(layout); + const LayoutUnit& layout = m_layoutOwnerMap->getPrevLayout().layoutUnit; + setLayout(layout); } void KXKBApp::menuActivated(int id) { - if( KxkbLabelController::START_MENU_ID <= id - && id < KxkbLabelController::START_MENU_ID + (int)kxkbConfig.m_layouts.count() ) - { - const LayoutUnit& layout = kxkbConfig.m_layouts[id - KxkbLabelController::START_MENU_ID]; - m_layoutOwnerMap->setCurrentLayout( layout ); - setLayout( layout ); - } - else if (id == KxkbLabelController::CONFIG_MENU_ID) + if (id >= KxkbSystemTray::START_MENU_ID && + id < KxkbSystemTray::START_MENU_ID + kxkbConfig.m_layouts.count()) + { + setLayout(id - KxkbSystemTray::START_MENU_ID); + } + else if (id == KxkbSystemTray::CONFIG_MENU_ID) { TDEProcess p; p << "tdecmshell" << "keyboard_layout"; p.start(TDEProcess::DontCare); - } - else if (id == KxkbLabelController::HELP_MENU_ID) - { - TDEApplication::kApplication()->invokeHelp(0, "kxkb"); - } -// else -// { -// quit(); -// } + } + else if (id == KxkbSystemTray::HELP_MENU_ID) + { + TDEApplication::kApplication()->invokeHelp(0, "kxkb"); + } } void KXKBApp::slotGroupChanged(uint group) { - if (group >= kxkbConfig.m_layouts.count()) - { - group = 0; - } - m_currentLayout = kxkbConfig.m_layouts[group]; - m_tray->setCurrentLayout(m_currentLayout); - maybeShowLayoutNotification(); + if (group < 0 || group >= kxkbConfig.m_layouts.count()) { + if (m_tray) { + m_tray->setError(i18n("Unknown")); + } + + if (kxkbConfig.m_enableNotify) { + showErrorNotification(i18n("Unknown")); + } + + return; + } + + m_currentLayout = kxkbConfig.m_layouts[group]; + m_layoutOwnerMap->setCurrentLayout(m_currentLayout); + + if (m_tray) { + m_tray->setCurrentLayout(m_currentLayout); + } + + if (kxkbConfig.m_enableNotify) { + showLayoutNotification(); + } } -void KXKBApp::maybeShowLayoutNotification() { - if (!kxkbConfig.m_enableNotify) return; - - TQString layoutName(m_rules->getLayoutName(m_currentLayout)); - bool useKMilo = kxkbConfig.m_notifyUseKMilo; - bool notificationSent = false; - - // Query KDED whether KMiloD is loaded - if (useKMilo) { - QCStringList modules; - TQCString replyType; - TQByteArray replyData; - if (kapp->dcopClient()->call("kded", "kded", "loadedModules()", - TQByteArray(), replyType, replyData)) - { - if (replyType == "QCStringList") { - TQDataStream reply(replyData, IO_ReadOnly); - reply >> modules; - - if (!modules.contains("kmilod")) { - useKMilo = false; - } - } - } - } +void KXKBApp::showLayoutNotification() { + bool useKMilo = kxkbConfig.m_notifyUseKMilo && isKMiloAvailable(), + notificationSent = false; - if (useKMilo) { - DCOPRef kmilo("kded", "kmilod"); - if (kmilo.send("displayText(TQString,TQPixmap)", layoutName, kapp->miniIcon())) - notificationSent = true; - } + TQString layoutName(m_rules->getLayoutName(m_currentLayout)); - if (!notificationSent) { - KNotifyClient::event(m_tray->winId(), "LayoutChange", layoutName); - } + if (useKMilo) { + DCOPRef kmilo("kded", "kmilod"); + if (kmilo.send("displayText(TQString,TQPixmap)", layoutName, kapp->miniIcon())) { + notificationSent = true; + } + } + + if (!notificationSent) { + KNotifyClient::event(m_tray->winId(), "LayoutChange", layoutName); + } +} + +void KXKBApp::showErrorNotification(TQString layout) { + bool useKMilo = kxkbConfig.m_notifyUseKMilo && isKMiloAvailable(), + notificationSent = false; + + if (useKMilo) { + DCOPRef kmilo("kded", "kmilod"); + if (kmilo.send("displayText(TQString,TQPixmap)", i18n("Error changing keyboard layout to '%1'").arg(layout), kapp->miniIcon())) { + notificationSent = true; + } + } + + if (!notificationSent) { + KNotifyClient::event(m_tray->winId(), "Error"); + } +} + +bool KXKBApp::isKMiloAvailable() { + QCStringList modules; + TQCString replyType; + TQByteArray replyData; + if (kapp->dcopClient()->call("kded", "kded", "loadedModules()", + TQByteArray(), replyType, replyData)) + { + if (replyType == "QCStringList") { + TQDataStream reply(replyData, IO_ReadOnly); + reply >> modules; + return modules.contains("kmilod"); + } + } + return false; } // TODO: we also have to handle deleted windows @@ -336,18 +336,18 @@ void KXKBApp::windowChanged(WId winId) } kdDebug() << "old WinId: " << m_prevWinId << ", new WinId: " << winId << endl; - + if( m_prevWinId != X11Helper::UNKNOWN_WINDOW_ID ) { // saving layout from previous window // m_layoutOwnerMap->setCurrentWindow(m_prevWinId); m_layoutOwnerMap->setCurrentLayout(m_currentLayout); } - + m_prevWinId = winId; if( winId != X11Helper::UNKNOWN_WINDOW_ID ) { m_layoutOwnerMap->setCurrentWindow(winId); const LayoutState& layoutState = m_layoutOwnerMap->getCurrentLayout(); - + if( layoutState.layoutUnit != m_currentLayout ) { kdDebug() << "switching to " << layoutState.layoutUnit.toPair() << " for " << winId << endl; setLayout(layoutState.layoutUnit); |