summaryrefslogtreecommitdiffstats
path: root/kxkb/kxkb.cpp
diff options
context:
space:
mode:
authorMavridis Philippe <[email protected]>2025-01-14 16:02:12 +0200
committerMavridis Philippe <[email protected]>2025-01-15 15:22:02 +0200
commitd3787d1dc415184f196dc5766c34082fd385e93c (patch)
tree504595b04aed6511d2024716c7686e4fa9240a29 /kxkb/kxkb.cpp
parentf140898676a7e083441b64f92dff7f4f10f6c7b4 (diff)
downloadtdebase-d3787d1dc415184f196dc5766c34082fd385e93c.tar.gz
tdebase-d3787d1dc415184f196dc5766c34082fd385e93c.zip
KXkb: Catch and process changes to Xkb layouts and options
The XKBExtension class reports likely configuration changes to the main app which then updates its internal options object accordingly and marks some option sets as 'tainted'. A notification is produced to inform the user that an external application such as setxkbmap has changed some options. The next time the keyboard layout configuration module opens a dialog box asks the user to select to load either the KXkb configuration on disk or the currently active Xkb options. In both cases the user can then save and apply the preferred version of the configuration. Other significant changes: * Make XKBExtension a singleton so that only one instance of the class exists. The extension is initialized on first use. * Add mutex to XKBExtension to prevent it from processing configuration changes likely caused by KXkb * XKBExtension::getServerOptions() now also returns layout and variant information in a XkbOptions struct * New KxkbConfig::setFromXkbOptions() member can update current configuration from a XkbOptions struct * Add proper copyright header to extension.* Signed-off-by: Mavridis Philippe <[email protected]>
Diffstat (limited to 'kxkb/kxkb.cpp')
-rw-r--r--kxkb/kxkb.cpp46
1 files changed, 30 insertions, 16 deletions
diff --git a/kxkb/kxkb.cpp b/kxkb/kxkb.cpp
index 8bced3fea..1a7faa534 100644
--- a/kxkb/kxkb.cpp
+++ b/kxkb/kxkb.cpp
@@ -24,7 +24,6 @@ DESCRIPTION
*/
#include <unistd.h>
-#include <stdlib.h>
#include <assert.h>
#include <tqregexp.h>
@@ -70,13 +69,10 @@ KXKBApp::KXKBApp(bool allowStyles, bool GUIenabled)
m_tray(NULL),
kWinModule(NULL)
{
- X11Helper::initializeTranslations();
- m_extension = new XKBExtension();
- if( !m_extension->init() ) {
- kdDebug() << "xkb initialization failed, exiting..." << endl;
- ::exit(1);
- }
- connect(m_extension, TQ_SIGNAL(groupChanged(uint)), this, TQ_SLOT(slotGroupChanged(uint)));
+ X11Helper::initializeTranslations();
+ XKBExtension *xkb = XKBExtension::the();
+ connect(xkb, TQ_SIGNAL(groupChanged(uint)), this, TQ_SLOT(slotGroupChanged(uint)));
+ connect(xkb, TQ_SIGNAL(optionsChanged()), this, TQ_SLOT(syncXkbOptions()));
m_layoutOwnerMap = new LayoutMap(kxkbConfig);
@@ -97,7 +93,6 @@ KXKBApp::~KXKBApp()
{
delete m_tray;
delete m_rules;
- delete m_extension;
delete m_layoutOwnerMap;
delete kWinModule;
delete keys;
@@ -203,7 +198,7 @@ void KXKBApp::readSettings()
void KXKBApp::applyXkbOptions()
{
XkbOptions options = kxkbConfig.getKXkbOptions();
- if (!m_extension->setXkbOptions(options)) {
+ if (!XKBExtension::the()->setXkbOptions(options)) {
kdWarning() << "Setting XKB options failed!" << endl;
}
}
@@ -236,14 +231,14 @@ bool KXKBApp::setLayout(const LayoutUnit& layoutUnit)
bool KXKBApp::setLayout(const uint group)
{
// If this group is already set, just show the notification and return
- if (m_extension->getGroup() == group) {
+ if (XKBExtension::the()->getGroup() == group) {
if (kxkbConfig.m_enableNotify) {
showLayoutNotification();
}
return true;
}
- bool ok = m_extension->setGroup(group);
+ bool ok = XKBExtension::the()->setGroup(group);
if (!ok) {
TQString layout = kxkbConfig.m_layouts[group].toPair();
if (m_tray) {
@@ -290,8 +285,8 @@ void KXKBApp::menuActivated(int id)
void KXKBApp::slotGroupChanged(uint group)
{
- kdDebug() << "slotGroupChanged: " << group << ", layout count: " << kxkbConfig.m_layouts.count() << endl;
if (group >= kxkbConfig.m_layouts.count()) {
+ kdError() << "[kxkb] unknown group requested: " << group << endl;
if (m_tray)
{
m_tray->setError(i18n("Unknown"));
@@ -317,7 +312,27 @@ void KXKBApp::slotGroupChanged(uint group)
}
}
-void KXKBApp::showLayoutNotification() {
+void KXKBApp::syncXkbOptions()
+{
+ XkbOptions options = XKBExtension::the()->getServerOptions();
+ if (kxkbConfig.setFromXkbOptions(options))
+ {
+ m_layoutOwnerMap->reset();
+ m_tray->initLayoutList(kxkbConfig.m_layouts, *m_rules);
+
+ // This event is not related to layout switching hence the notification-related
+ // options do not apply here, but only options from the system notifications
+ // control module.
+ KNotifyClient::event(
+ m_tray->winId(), "ExternalChange",
+ i18n("An external application has modified the active keyboard configuration"));
+ }
+
+ slotGroupChanged(XKBExtension::the()->getGroup());
+}
+
+void KXKBApp::showLayoutNotification()
+{
bool useKMilo = kxkbConfig.m_notifyUseKMilo && isKMiloAvailable(),
notificationSent = false;
@@ -396,7 +411,6 @@ void KXKBApp::windowChanged(WId winId)
}
}
-
void KXKBApp::slotSettingsChanged(int category)
{
if (category == TDEApplication::SETTINGS_SHORTCUTS) {
@@ -408,7 +422,7 @@ void KXKBApp::slotSettingsChanged(int category)
bool KXKBApp::x11EventFilter(XEvent *e) {
// let the extension process the event and emit signals if necessary
- m_extension->processXEvent(e);
+ XKBExtension::the()->processXEvent(e);
return TDEApplication::x11EventFilter(e);
}