Skip to content

Commit d3476f1

Browse files
authored
Port to Qt6 and use .ui file (#30)
...but keep the Gtk version around for the time being. Also remove gsettings get/set calls (e.g. for gtk theme, icon theme and cursor theme) to keep separation boundaries cleaner for people who may want to use labwc-tweaks to configure the compositor alone and use other settings clients for Gtk and Qt related settings. Remove the optional call to labwc-gtktheme because it is quite hacky and its Gtk theme parsing is far from ideal.
1 parent 67adbed commit d3476f1

File tree

8 files changed

+531
-0
lines changed

8 files changed

+531
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

CMakeLists.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
project(labwc-tweaks VERSION 0.0 LANGUAGES C CXX)
4+
5+
set(CMAKE_AUTOUIC ON)
6+
set(CMAKE_AUTOMOC ON)
7+
set(CMAKE_AUTORCC ON)
8+
9+
set(CMAKE_CXX_STANDARD 17)
10+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
11+
12+
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=undefined")
13+
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize=undefined")
14+
15+
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets)
16+
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
17+
find_package(PkgConfig REQUIRED)
18+
pkg_search_module(GLIB REQUIRED glib-2.0)
19+
find_package(LibXml2 REQUIRED)
20+
21+
qt_add_executable(${CMAKE_PROJECT_NAME}
22+
MANUAL_FINALIZATION
23+
tweaks-qt/main.cpp
24+
tweaks-qt/mainwindow.cpp
25+
tweaks-qt/mainwindow.h
26+
tweaks-qt/mainwindow.ui
27+
environment.c
28+
environment.h
29+
theme.c
30+
theme.h
31+
xml.c
32+
xml.h
33+
keyboard-layouts.c
34+
keyboard-layouts.h
35+
)
36+
37+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE .)
38+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${GLIB_INCLUDE_DIRS})
39+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${LIBXML2_INCLUDE_DIR})
40+
41+
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt6::Widgets ${GLIB_LDFLAGS} ${LIBXML2_LIBRARIES})
42+
target_link_libraries(${CMAKE_PROJECT_NAME} INTERFACE ${GLIB_LDFLAGS})
43+
44+
#target_link_options(${CMAKE_PROJECT_NAME} BEFORE PUBLIC -fsanitize=undefined PUBLIC -fsanitize=address)
45+
46+
include(GNUInstallDirs)
47+
install(TARGETS ${CMAKE_PROJECT_NAME}
48+
BUNDLE DESTINATION .
49+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
50+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
51+
)
52+
53+
qt_finalize_executable(${CMAKE_PROJECT_NAME})

tweaks-qt/.clang-format

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
BasedOnStyle: WebKit
2+
Standard: c++20
3+
ColumnLimit: 100
4+
CommentPragmas: "^!|^:|^ SPDX-License-Identifier:"
5+
PointerBindsToType: false
6+
SpaceAfterTemplateKeyword: false
7+
BreakBeforeBinaryOperators: NonAssignment
8+
BreakBeforeBraces: Custom
9+
BraceWrapping:
10+
AfterClass: true
11+
AfterControlStatement: false
12+
AfterEnum: false
13+
AfterFunction: true
14+
AfterNamespace: false
15+
AfterObjCDeclaration: false
16+
AfterStruct: true
17+
AfterUnion: false
18+
BeforeCatch: false
19+
BeforeElse: false
20+
IndentBraces: false
21+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
22+
ConstructorInitializerIndentWidth: 4
23+
ContinuationIndentWidth: 8
24+
NamespaceIndentation: None
25+
IndentPPDirectives: AfterHash
26+
PPIndentWidth: 2
27+
AlignAfterOpenBracket: true
28+
AlwaysBreakTemplateDeclarations: true
29+
AllowShortFunctionsOnASingleLine: Inline
30+
SortIncludes: false
31+
ForEachMacros: [ foreach, Q_FOREACH, forever, Q_FOREVER ]
32+
BreakConstructorInitializers: BeforeColon
33+
FixNamespaceComments: true
34+
ShortNamespaceLines: 1
35+
AlignEscapedNewlines: Left
36+
SpaceBeforeCpp11BracedList: false
37+

tweaks-qt/.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*.{cpp,h}]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
charset = utf-8
7+
trim_trailing_whitespace = true
8+
indent_style = space
9+
indent_size = 4
10+
max_line_length = 100

tweaks-qt/main.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "mainwindow.h"
2+
3+
#include <QApplication>
4+
5+
int main(int argc, char *argv[])
6+
{
7+
QApplication a(argc, argv);
8+
MainWindow w;
9+
w.show();
10+
return a.exec();
11+
}

tweaks-qt/mainwindow.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include <QDebug>
2+
#include <glib.h>
3+
#include <string>
4+
#include <unistd.h>
5+
#include "mainwindow.h"
6+
#include "./ui_mainwindow.h"
7+
8+
extern "C" {
9+
#include "environment.h"
10+
#include "keyboard-layouts.h"
11+
#include "theme.h"
12+
#include "xml.h"
13+
}
14+
15+
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
16+
{
17+
ui->setupUi(this);
18+
19+
std::string config_file = std::getenv("HOME");
20+
config_file += "/.config/labwc/rc.xml";
21+
xml_init(config_file.data());
22+
xml_setup_nodes();
23+
24+
QObject::connect(ui->quit, &QPushButton::clicked, this, &MainWindow::quitSlot);
25+
QObject::connect(ui->update, &QPushButton::clicked, this, &MainWindow::updateSlot);
26+
27+
activate();
28+
}
29+
30+
MainWindow::~MainWindow()
31+
{
32+
delete ui;
33+
xml_finish();
34+
}
35+
36+
static const char *first_field(char *s, char delim)
37+
{
38+
char *p = strchr(s, delim);
39+
if (p) {
40+
*p = '\0';
41+
}
42+
return s;
43+
}
44+
45+
void MainWindow::activate()
46+
{
47+
/* # APPEARANCE */
48+
49+
/* Openbox Theme */
50+
struct themes openbox_themes = { 0 };
51+
theme_find(&openbox_themes, "themes", "openbox-3/themerc");
52+
int active = -1;
53+
char *active_id = xml_get((char *)"/labwc_config/theme/name");
54+
for (int i = 0; i < openbox_themes.nr; ++i) {
55+
struct theme *theme = openbox_themes.data + i;
56+
if (active_id && !strcmp(theme->name, active_id)) {
57+
active = i;
58+
}
59+
ui->openboxTheme->addItem(theme->name);
60+
}
61+
if (active != -1) {
62+
ui->openboxTheme->setCurrentIndex(active);
63+
}
64+
theme_free_vector(&openbox_themes);
65+
66+
/* Corner Radius */
67+
ui->cornerRadius->setValue(xml_get_int((char *)"/labwc_config/theme/cornerradius"));
68+
69+
/* # MOUSE & TOUCHPAD */
70+
71+
/* Cursor Theme */
72+
struct themes cursor_themes = { 0 };
73+
theme_find(&cursor_themes, "icons", "cursors");
74+
75+
active_id = getenv("XCURSOR_THEME") ?: (char *)"";
76+
active = -1;
77+
for (int i = 0; i < cursor_themes.nr; ++i) {
78+
struct theme *theme = cursor_themes.data + i;
79+
if (!strcmp(theme->name, active_id)) {
80+
active = i;
81+
}
82+
ui->cursorTheme->addItem(theme->name);
83+
}
84+
if (active != -1) {
85+
ui->cursorTheme->setCurrentIndex(active);
86+
}
87+
theme_free_vector(&cursor_themes);
88+
89+
/* Cursor Size */
90+
ui->cursorSize->setValue(atoi(getenv("XCURSOR_SIZE") ?: "24"));
91+
92+
/* Natural Scroll */
93+
ui->naturalScroll->addItem("no");
94+
ui->naturalScroll->addItem("yes");
95+
ui->naturalScroll->setCurrentIndex(
96+
xml_get_bool_text((char *)"/labwc_config/libinput/device/naturalscroll"));
97+
98+
/* # LANGUAGE */
99+
100+
/* Keyboard Layout */
101+
GList *keyboard_layouts = NULL;
102+
keyboard_layouts_init(&keyboard_layouts, (char *)"/usr/share/X11/xkb/rules/evdev.lst");
103+
char xkb_default_layout[1024];
104+
environment_get(xkb_default_layout, sizeof(xkb_default_layout), "XKB_DEFAULT_LAYOUT");
105+
active = -1;
106+
107+
GList *iter;
108+
int i = 0;
109+
for (iter = keyboard_layouts; iter; iter = iter->next) {
110+
struct layout *layout = (struct layout *)iter->data;
111+
if (!strcmp(layout->lang, first_field(xkb_default_layout, ','))) {
112+
active = i;
113+
}
114+
char buf[256];
115+
snprintf(buf, sizeof(buf), "%s %s", layout->lang, layout->description);
116+
ui->keyboardLayout->addItem(buf);
117+
++i;
118+
}
119+
if (active != -1) {
120+
ui->keyboardLayout->setCurrentIndex(active);
121+
}
122+
keyboard_layouts_finish(keyboard_layouts);
123+
}
124+
125+
void MainWindow::quitSlot(void)
126+
{
127+
this->close();
128+
}
129+
130+
void MainWindow::updateSlot(void)
131+
{
132+
/* ~/.config/labwc/rc.xml */
133+
xml_set_num((char *)"/labwc_config/theme/cornerradius", ui->cornerRadius->value());
134+
xml_set((char *)"/labwc_config/theme/name", ui->openboxTheme->currentText().toLatin1().data());
135+
xml_set((char *)"/labwc_config/libinput/device/naturalscroll",
136+
ui->naturalScroll->currentText().toLatin1().data());
137+
xml_save();
138+
139+
/* ~/.config/labwc/environment */
140+
environment_set("XCURSOR_THEME", ui->cursorTheme->currentText().toLatin1().data());
141+
environment_set_num("XCURSOR_SIZE", ui->cursorSize->value());
142+
environment_set("XKB_DEFAULT_LAYOUT",
143+
first_field(ui->keyboardLayout->currentText().toLatin1().data(), ' '));
144+
145+
/* reconfigure labwc */
146+
if (!fork()) {
147+
execl("/bin/sh", "/bin/sh", "-c", "killall -s SIGHUP labwc", (void *)NULL);
148+
}
149+
}

tweaks-qt/mainwindow.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef MAINWINDOW_H
2+
#define MAINWINDOW_H
3+
4+
#include <QMainWindow>
5+
6+
QT_BEGIN_NAMESPACE
7+
namespace Ui {
8+
class MainWindow;
9+
}
10+
QT_END_NAMESPACE
11+
12+
class MainWindow : public QMainWindow
13+
{
14+
Q_OBJECT
15+
16+
public:
17+
MainWindow(QWidget *parent = nullptr);
18+
~MainWindow();
19+
void activate();
20+
21+
private slots:
22+
void quitSlot(void);
23+
void updateSlot(void);
24+
25+
private:
26+
Ui::MainWindow *ui;
27+
};
28+
#endif // MAINWINDOW_H

0 commit comments

Comments
 (0)