Suppress compiler warnings about unused function parameters
[lxde/liblxqt.git] / lxqtapplication.cpp
CommitLineData
8966cbec 1/* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
b9223fe7 4 * LXQt - a lightweight, Qt based, desktop toolset
8966cbec 5 * http://razor-qt.org
6 *
7 * Copyright: 2012-2013 Razor team
8 * Authors:
9 * Petr Vanek <petr@scribus.info>
10 *
11 * This program or library is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20
21 * You should have received a copy of the GNU Lesser General
22 * Public License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
25 *
26 * END_COMMON_COPYRIGHT_HEADER */
27
e6389bfc 28#include <QDir>
f18f98db 29
077c1e76 30#include "lxqtapplication.h"
82830dc2 31#include "lxqtsettings.h"
f18f98db 32
e6389bfc 33#include <XdgDirs>
afd3b116 34
f05ba5af 35using namespace LXQt;
8966cbec 36
00f0a23a
AS
37#define COLOR_DEBUG "\033[32;2m"
38#define COLOR_WARN "\033[33;2m"
2f7229d2 39#define COLOR_CRITICAL "\033[31;1m"
40#define COLOR_FATAL "\033[33;1m"
41#define COLOR_RESET "\033[0m"
42
43#define QAPP_NAME qApp ? qApp->objectName().toUtf8().constData() : ""
44
619f3aee 45#include <cstdio>
3048adf5 46#include <unistd.h>
70dd4459
PK
47#include <cstring>
48#include <csignal>
686212f0 49#include <cerrno>
70dd4459 50#include <sys/socket.h>
619f3aee 51#include <QDateTime>
70dd4459
PK
52#include <QDebug>
53#include <QSocketNotifier>
bc341bc6 54/*! \brief Log qDebug input to file
5af80cab 55Used only in pure Debug builds or when is the system environment
db4aaddf 56variable LXQT_DEBUG set
619f3aee 57*/
2d13fe11
HJYP
58void dbgMessageOutput(QtMsgType type, const QMessageLogContext &ctx, const QString & msgStr)
59{
7cce0c05 60 Q_UNUSED(ctx)
2d13fe11
HJYP
61 QByteArray msgBuf = msgStr.toUtf8();
62 const char* msg = msgBuf.constData();
cd4d87e4 63 QDir dir(XdgDirs::configHome().toUtf8() + QLatin1String("/lxqt"));
00f0a23a
AS
64 dir.mkpath(".");
65
3048adf5
AM
66 const char* typestr;
67 const char* color;
619f3aee 68 switch (type) {
69 case QtDebugMsg:
3048adf5
AM
70 typestr = "Debug";
71 color = COLOR_DEBUG;
619f3aee 72 break;
73 case QtWarningMsg:
3048adf5
AM
74 typestr = "Warning";
75 color = COLOR_WARN;
619f3aee 76 break;
77 case QtFatalMsg:
3048adf5
AM
78 typestr = "Fatal";
79 color = COLOR_FATAL;
80 break;
81 default: // QtCriticalMsg
82 typestr = "Critical";
83 color = COLOR_CRITICAL;
619f3aee 84 }
3048adf5
AM
85
86 QByteArray dt = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8();
87 if (isatty(STDERR_FILENO))
88 fprintf(stderr, "%s %s(%p) %s: %s%s\n", color, QAPP_NAME, qApp, typestr, msg, COLOR_RESET);
89 else
90 fprintf(stderr, "%s(%p) %s: %s\n", QAPP_NAME, qApp, typestr, msg);
91
92 FILE *f = fopen(dir.absoluteFilePath("debug.log").toUtf8().constData(), "a+");
93 fprintf(f, "%s %s(%p) %s: %s\n", dt.constData(), QAPP_NAME, qApp, typestr, msg);
619f3aee 94 fclose(f);
3048adf5
AM
95
96 if (type == QtFatalMsg)
97 abort();
619f3aee 98}
8966cbec 99
077c1e76 100Application::Application(int &argc, char** argv)
8966cbec 101 : QApplication(argc, argv)
102{
619f3aee 103#ifdef DEBUG
2d13fe11 104 qInstallMessageHandler(dbgMessageOutput);
5af80cab 105#else
db4aaddf 106 if (!qgetenv("LXQT_DEBUG").isNull())
2d13fe11 107 qInstallMessageHandler(dbgMessageOutput);
619f3aee 108#endif
109
825771a5 110 setWindowIcon(QIcon(QString(LXQT_GRAPHICS_DIR) + "/lxqt_logo.png"));
db4aaddf 111 connect(Settings::globalSettings(), SIGNAL(lxqtThemeChanged()), this, SLOT(updateTheme()));
63a934d5
AS
112 updateTheme();
113}
8966cbec 114
70dd4459
PK
115Application::Application(int &argc, char** argv, bool handleQuitSignals)
116 : Application(argc, argv)
117{
118 if (handleQuitSignals)
119 {
120 QList<int> signo_list = {SIGINT, SIGTERM, SIGHUP};
121 connect(this, &Application::unixSignal, [this, signo_list] (int signo)
122 {
123 if (signo_list.contains(signo))
124 quit();
125 });
126 listenToUnixSignals(signo_list);
127 }
128}
8966cbec 129
077c1e76 130void Application::updateTheme()
63a934d5 131{
d7858989 132 const QString styleSheetKey = QFileInfo(applicationFilePath()).fileName();
db4aaddf 133 setStyleSheet(lxqtTheme.qss(styleSheetKey));
63a934d5 134 emit themeChanged();
8966cbec 135}
70dd4459
PK
136
137namespace
138{
d2c9e68d 139 class SignalHandler
70dd4459 140 {
d2c9e68d 141 public:
142 static void signalHandler(int signo)
143 {
d7858989 144 const int ret = write(instance->mSignalSock[0], &signo, sizeof (int));
d2c9e68d 145 if (sizeof (int) != ret)
146 qCritical() << QStringLiteral("unable to write into socketpair, %1").arg(strerror(errno));
147 }
148
149 public:
150 template <class Lambda>
151 SignalHandler(Lambda signalEmitter)
152 : mSignalSock{-1, -1}
153 {
154 if (0 != socketpair(AF_UNIX, SOCK_STREAM, 0, mSignalSock))
155 {
156 qCritical() << QStringLiteral("unable to create socketpair for correct signal handling: %1)").arg(strerror(errno));
157 return;
158 }
70dd4459 159
d2c9e68d 160 mNotifier.reset(new QSocketNotifier(mSignalSock[1], QSocketNotifier::Read));
161 QObject::connect(mNotifier.data(), &QSocketNotifier::activated, [this, signalEmitter] {
162 int signo = 0;
163 int ret = read(mSignalSock[1], &signo, sizeof (int));
164 if (sizeof (int) != ret)
165 qCritical() << QStringLiteral("unable to read signal from socketpair, %1").arg(strerror(errno));
166 signalEmitter(signo);
167 });
168 }
70dd4459 169
d2c9e68d 170 ~SignalHandler()
70dd4459 171 {
d2c9e68d 172 close(mSignalSock[0]);
173 close(mSignalSock[1]);
70dd4459
PK
174 }
175
d2c9e68d 176 void listenToSignals(QList<int> const & signoList)
177 {
178 struct sigaction sa;
179 sa.sa_handler = signalHandler;
180 sigemptyset(&sa.sa_mask);
181 sa.sa_flags = 0;
182 for (auto const & signo : signoList)
183 sigaction(signo, &sa, nullptr);
184 }
185
186 public:
187 static QScopedPointer<SignalHandler> instance;
188
189 private:
190 int mSignalSock[2];
191 QScopedPointer<QSocketNotifier> mNotifier;
192 };
193
194 QScopedPointer<SignalHandler> SignalHandler::instance;
195}
196
197void Application::listenToUnixSignals(QList<int> const & signoList)
198{
199 static QScopedPointer<QSocketNotifier> signal_notifier;
70dd4459 200
d2c9e68d 201 if (SignalHandler::instance.isNull())
202 SignalHandler::instance.reset(new SignalHandler{[this] (int signo) { emit unixSignal(signo); }});
203 SignalHandler::instance->listenToSignals(signoList);
70dd4459 204}