polybar-dwm/src/main.cpp

153 lines
5.0 KiB
C++
Raw Normal View History

2016-06-15 03:32:35 +00:00
#include <X11/Xlib-xcb.h>
#include "common.hpp"
#include "components/bar.hpp"
2016-06-15 03:32:35 +00:00
#include "components/command_line.hpp"
#include "components/config.hpp"
#include "components/controller.hpp"
#include "components/ipc.hpp"
2016-06-15 03:32:35 +00:00
#include "components/logger.hpp"
#include "components/parser.hpp"
#include "components/renderer.hpp"
2016-06-15 03:32:35 +00:00
#include "config.hpp"
2016-11-20 22:04:31 +00:00
#include "utils/env.hpp"
#include "utils/file.hpp"
2016-06-15 03:32:35 +00:00
#include "utils/inotify.hpp"
2016-12-03 14:46:48 +00:00
#include "utils/process.hpp"
#include "x11/connection.hpp"
#include "x11/tray_manager.hpp"
2016-11-20 22:04:31 +00:00
#include "x11/xutils.hpp"
2016-06-15 03:32:35 +00:00
2016-11-19 05:22:44 +00:00
using namespace polybar;
2016-06-15 03:32:35 +00:00
2016-11-25 07:42:31 +00:00
int main(int argc, char** argv) {
2016-06-15 03:32:35 +00:00
// clang-format off
const command_line::options opts{
2016-12-09 11:22:58 +00:00
command_line::option{"-h", "--help", "Show help options"},
2016-06-15 03:32:35 +00:00
command_line::option{"-v", "--version", "Print version information"},
2016-12-09 11:22:58 +00:00
command_line::option{"-l", "--log", "Set the logging verbosity (default: WARNING)", "LEVEL", {"error", "warning", "info", "trace"}},
2016-06-15 03:32:35 +00:00
command_line::option{"-q", "--quiet", "Be quiet (will override -l)"},
command_line::option{"-c", "--config", "Path to the configuration file", "FILE"},
command_line::option{"-r", "--reload", "Reload when the configuration has been modified"},
command_line::option{"-d", "--dump", "Show value of PARAM in section [bar_name]", "PARAM"},
command_line::option{"-w", "--print-wmname", "Print the generated WM_NAME"},
command_line::option{"-s", "--stdout", "Output data to stdout instead of drawing the X window"},
};
// clang-format on
2016-12-03 15:44:08 +00:00
uint8_t exit_code{EXIT_SUCCESS};
bool reload{false};
2016-12-09 11:22:58 +00:00
logger& logger{const_cast<decltype(logger)>(logger::make(loglevel::WARNING))};
2016-12-03 14:46:48 +00:00
try {
//==================================================
// Parse command line arguments
//==================================================
string scriptname{argv[0]};
vector<string> args{argv + 1, argv + argc};
2016-12-09 11:24:01 +00:00
cliparser::make_type cli{cliparser::make(move(scriptname), move(opts))};
cli->process_input(args);
2016-12-03 14:46:48 +00:00
if (cli->has("quiet")) {
2016-12-03 14:46:48 +00:00
logger.verbosity(loglevel::ERROR);
} else if (cli->has("log")) {
2016-12-09 11:22:58 +00:00
logger.verbosity(logger::parse_verbosity(cli->get("log")));
2016-12-03 14:46:48 +00:00
}
if (cli->has("help")) {
cli->usage();
return EXIT_SUCCESS;
} else if (cli->has("version")) {
2016-12-03 14:46:48 +00:00
print_build_info(version_details(args));
return EXIT_SUCCESS;
2016-12-03 14:46:48 +00:00
} else if (args.empty() || args[0][0] == '-') {
cli->usage();
return EXIT_FAILURE;
2016-12-03 14:46:48 +00:00
}
//==================================================
// Connect to X server
//==================================================
XInitThreads();
// Store the xcb connection pointer with a disconnect deleter
unique_ptr<xcb_connection_t, xutils::xcb_connection_deleter> xcbconn{xutils::get_connection()};
if (!xcbconn) {
logger.err("A connection to X could not be established... ");
return EXIT_FAILURE;
}
connection& conn{connection::make(&*xcbconn)};
conn.preload_atoms();
conn.query_extensions();
conn.ensure_event_mask(conn.root(), XCB_EVENT_MASK_PROPERTY_CHANGE);
2016-12-03 14:46:48 +00:00
//==================================================
// Load user configuration
//==================================================
string confpath;
2016-12-03 14:46:48 +00:00
if (cli->has("config")) {
confpath = cli->get("config");
2016-12-03 14:46:48 +00:00
} else if (env_util::has("XDG_CONFIG_HOME")) {
confpath = env_util::get("XDG_CONFIG_HOME") + "/polybar/config";
2016-12-03 14:46:48 +00:00
} else if (env_util::has("HOME")) {
confpath = env_util::get("HOME") + "/.config/polybar/config";
2016-12-03 14:46:48 +00:00
} else {
throw application_error("Define configuration using --config=PATH");
}
config::make_type conf{config::make(move(confpath), args[0])};
2016-12-03 14:46:48 +00:00
//==================================================
// Dump requested data
//==================================================
if (cli->has("dump")) {
std::cout << conf.get<string>(conf.section(), cli->get("dump")) << std::endl;
return EXIT_SUCCESS;
}
if (cli->has("print-wmname")) {
std::cout << bar::make(true)->settings().wmname << std::endl;
return EXIT_SUCCESS;
2016-12-03 14:46:48 +00:00
}
//==================================================
// Create controller and run application
2016-12-03 14:46:48 +00:00
//==================================================
unique_ptr<ipc> ipc{};
unique_ptr<inotify_watch> config_watch{};
if (conf.get<bool>(conf.section(), "enable-ipc", false)) {
ipc = ipc::make();
2016-12-03 14:46:48 +00:00
}
if (cli->has("reload")) {
config_watch = inotify_util::make_watch(conf.filepath());
2016-06-15 03:32:35 +00:00
}
2016-12-03 14:46:48 +00:00
auto ctrl = controller::make(move(ipc), move(config_watch));
if (!ctrl->run(cli->has("stdout"))) {
2016-12-03 14:46:48 +00:00
reload = true;
}
} catch (const exception& err) {
logger.err(err.what());
exit_code = EXIT_FAILURE;
}
logger.info("Waiting for spawned processes to end");
while (process_util::notify_childprocess()) {
;
}
2016-06-15 03:32:35 +00:00
if (reload) {
2016-12-09 11:43:31 +00:00
logger.info("Re-launching application...");
process_util::exec(move(argv[0]), move(argv));
2016-12-03 14:46:48 +00:00
}
2016-11-25 07:42:31 +00:00
logger.info("Reached end of application...");
return exit_code;
2016-06-15 03:32:35 +00:00
}