Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use hardcoded xkb rules file paths. #1695

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
26 changes: 24 additions & 2 deletions plugin-kbindicator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,29 @@ set(LIBRARIES

find_package(XCB REQUIRED COMPONENTS xcb xcb-xkb)
find_package(XKBCommon REQUIRED COMPONENTS XKBCommon X11)
find_package(X11 REQUIRED)
find_package(Qt5 ${QT_MINIMUM_VERSION} REQUIRED COMPONENTS X11Extras Xml)

include_directories(${XCB_INCLUDE_DIRS})
if(NOT X11_Xkbfile_FOUND)
MESSAGE(FATAL_ERROR "'libxkbfile' not found. Aborting")
endif()

find_package(PkgConfig REQUIRED)
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=xkb_base xkeyboard-config
OUTPUT_VARIABLE XKB_RULES_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT EXISTS "${XKB_RULES_DIR}")
message(FATAL_ERROR "Couldn't find XKB rules location: \"${XKB_RULES_DIR}\".")
endif()

message(STATUS "X11_xkbfile_INCLUDE_PATH: ${X11_xkbfile_INCLUDE_PATH}")
message(STATUS "X11_INCLUDE_DIR: ${X11_INCLUDE_DIR}")

include_directories(
${XCB_INCLUDE_DIRS}
${X11_xkbfile_INCLUDE_PATH}
)

set(HEADERS
${HEADERS}
Expand All @@ -48,11 +68,13 @@ set(SOURCES
set(LIBRARIES
${LIBRARIES}
${XCB_LIBRARIES}
${X11_xkbfile_LIB}
XKBCommon::XKBCommon
XKBCommon::X11
Qt5::Xml
)

add_definitions(-DX11_ENABLED)
add_definitions(-DX11_ENABLED -DXKB_RULES_DIR=\"${XKB_RULES_DIR}\")


BUILD_LXQT_PLUGIN(${PLUGIN})
59 changes: 57 additions & 2 deletions plugin-kbindicator/src/x11/kbdlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@
#include <QAbstractNativeEventFilter>
#include <QDebug>
#include <QFile>
#include <QX11Info>
#include <QDomDocument>
#include "kbdlayout.h"

#include <xkbcommon/xkbcommon-x11.h>
#include <xcb/xcb.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>

// Note: We need to override "explicit" as this is a C++ keyword. But it is
// used as variable name in xkb.h. This is causing a failure in C++ compile
Expand All @@ -45,6 +49,56 @@
#include "../kbdinfo.h"
#include "../controls.h"

static QString xkbRulesDir();
static QString xkbRulesFile();
static QString xkbRulesName();
static void _lxqt_xkb_free_var_defs(XkbRF_VarDefsRec *var_defs);

static QString xkbRulesDir()
{
return QStringLiteral(XKB_RULES_DIR);
}

static QString xkbRulesFile()
{
QString rulesFile;
const QString rules = xkbRulesName();
const QString xkbDir = xkbRulesDir();
if (!rules.isEmpty()) {
rulesFile = QStringLiteral("%1/rules/%2.xml").arg(xkbDir, rules);
} else { // default
rulesFile = QStringLiteral("%1/rules/evdev.xml").arg(xkbDir);
}
return rulesFile;
}

static QString xkbRulesName()
{
if (!QX11Info::isPlatformX11()) {
return QString();
}
XkbRF_VarDefsRec v{};
char *file = nullptr;

if (XkbRF_GetNamesProp(QX11Info::display(), &file, &v) && file != nullptr) {
const QString name = QString::fromUtf8(file);
XFree(file);
_lxqt_xkb_free_var_defs(&v);
return name;
}
return {};
}

static void _lxqt_xkb_free_var_defs(XkbRF_VarDefsRec *var_defs)
{
if (var_defs == nullptr)
return;

free(static_cast<void *>(var_defs->model));
free(static_cast<void *>(var_defs->layout));
free(static_cast<void *>(var_defs->variant));
free(static_cast<void *>(var_defs->options));
}
namespace pimpl {

struct LangInfo
Expand Down Expand Up @@ -245,10 +299,11 @@ class X11Kbd: public QAbstractNativeEventFilter
static LangInfo def{QStringLiteral("Unknown"), QStringLiteral("??"), QStringLiteral("None")};
static QHash<QString, LangInfo> names;
if (names.empty()){
if(QFile::exists(QStringLiteral("/usr/share/X11/xkb/rules/evdev.xml"))){
const QString rulesFile{xkbRulesFile()};
if(QFile::exists(rulesFile)){
QDomDocument doc;

QFile file(QStringLiteral("/usr/share/X11/xkb/rules/evdev.xml"));
QFile file(rulesFile);
if (file.open(QIODevice::ReadOnly)){
if (doc.setContent(&file)) {
QDomElement docElem = doc.documentElement();
Expand Down