2016-06-14 23:32:35 -04:00
|
|
|
#include "common.hpp"
|
2016-12-19 23:05:43 -05:00
|
|
|
#include "components/bar.hpp"
|
2016-06-14 23:32:35 -04:00
|
|
|
#include "components/command_line.hpp"
|
|
|
|
#include "components/config.hpp"
|
|
|
|
#include "components/controller.hpp"
|
2016-12-19 23:05:43 -05:00
|
|
|
#include "components/ipc.hpp"
|
2016-06-14 23:32:35 -04:00
|
|
|
#include "components/logger.hpp"
|
2016-12-19 23:05:43 -05:00
|
|
|
#include "components/parser.hpp"
|
|
|
|
#include "components/renderer.hpp"
|
2017-01-10 21:07:28 -05:00
|
|
|
#include "settings.hpp"
|
2016-11-20 17:04:31 -05:00
|
|
|
#include "utils/env.hpp"
|
2016-12-19 23:05:43 -05:00
|
|
|
#include "utils/file.hpp"
|
2016-06-14 23:32:35 -04:00
|
|
|
#include "utils/inotify.hpp"
|
2017-01-01 02:58:33 -05:00
|
|
|
#include "utils/io.hpp"
|
2016-12-03 09:46:48 -05:00
|
|
|
#include "utils/process.hpp"
|
2016-12-19 23:05:43 -05:00
|
|
|
#include "x11/connection.hpp"
|
|
|
|
#include "x11/tray_manager.hpp"
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
using namespace polybar;
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-11-25 02:42:31 -05:00
|
|
|
int main(int argc, char** argv) {
|
2016-06-14 23:32:35 -04:00
|
|
|
// clang-format off
|
|
|
|
const command_line::options opts{
|
2017-01-12 21:52:56 -05:00
|
|
|
command_line::option{"-h", "--help", "Display this help and exit"},
|
|
|
|
command_line::option{"-v", "--version", "Display build details and exit"},
|
2016-12-09 06:22:58 -05:00
|
|
|
command_line::option{"-l", "--log", "Set the logging verbosity (default: WARNING)", "LEVEL", {"error", "warning", "info", "trace"}},
|
2016-06-14 23:32:35 -04: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"},
|
2017-01-12 21:52:56 -05:00
|
|
|
command_line::option{"-d", "--dump", "Print value of PARAM in section [bar_name] and exit", "PARAM"},
|
|
|
|
command_line::option{"-m", "--list-monitors", "Print list of available monitors and exit"},
|
|
|
|
command_line::option{"-w", "--print-wmname", "Print the generated WM_NAME and exit"},
|
2016-06-14 23:32:35 -04:00
|
|
|
command_line::option{"-s", "--stdout", "Output data to stdout instead of drawing the X window"},
|
|
|
|
};
|
|
|
|
// clang-format on
|
|
|
|
|
2016-12-03 10:44:08 -05:00
|
|
|
uint8_t exit_code{EXIT_SUCCESS};
|
|
|
|
bool reload{false};
|
|
|
|
|
2016-12-09 06:22:58 -05:00
|
|
|
logger& logger{const_cast<decltype(logger)>(logger::make(loglevel::WARNING))};
|
2016-12-05 14:41:00 -05:00
|
|
|
|
2016-12-03 09:46:48 -05:00
|
|
|
try {
|
|
|
|
//==================================================
|
|
|
|
// Parse command line arguments
|
|
|
|
//==================================================
|
|
|
|
string scriptname{argv[0]};
|
2016-12-09 05:32:41 -05:00
|
|
|
vector<string> args{argv + 1, argv + argc};
|
|
|
|
|
2017-01-10 21:07:28 -05:00
|
|
|
command_line::parser::make_type cli{command_line::parser::make(move(scriptname), move(opts))};
|
2016-12-05 14:41:00 -05:00
|
|
|
cli->process_input(args);
|
2016-12-03 09:46:48 -05:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
if (cli->has("quiet")) {
|
2016-12-03 09:46:48 -05:00
|
|
|
logger.verbosity(loglevel::ERROR);
|
2016-12-05 14:41:00 -05:00
|
|
|
} else if (cli->has("log")) {
|
2016-12-09 06:22:58 -05:00
|
|
|
logger.verbosity(logger::parse_verbosity(cli->get("log")));
|
2016-12-03 09:46:48 -05:00
|
|
|
}
|
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
if (cli->has("help")) {
|
|
|
|
cli->usage();
|
2016-12-19 23:05:43 -05:00
|
|
|
return EXIT_SUCCESS;
|
2016-12-05 14:41:00 -05:00
|
|
|
} else if (cli->has("version")) {
|
2016-12-03 09:46:48 -05:00
|
|
|
print_build_info(version_details(args));
|
2016-12-19 23:05:43 -05:00
|
|
|
return EXIT_SUCCESS;
|
2016-12-03 09:46:48 -05:00
|
|
|
}
|
|
|
|
|
2016-12-23 20:55:21 -05:00
|
|
|
//==================================================
|
|
|
|
// Connect to X server
|
|
|
|
//==================================================
|
|
|
|
XInitThreads();
|
2016-12-31 01:39:50 -05:00
|
|
|
Display* xdisplay{XOpenDisplay(nullptr)};
|
2016-12-23 20:55:21 -05:00
|
|
|
|
2016-12-31 01:39:50 -05:00
|
|
|
if (xdisplay == nullptr) {
|
2016-12-23 20:55:21 -05:00
|
|
|
logger.err("A connection to X could not be established... ");
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-12-31 01:39:50 -05:00
|
|
|
connection& conn{connection::make(xdisplay)};
|
2016-12-23 20:55:21 -05:00
|
|
|
conn.ensure_event_mask(conn.root(), XCB_EVENT_MASK_PROPERTY_CHANGE);
|
|
|
|
|
2017-01-12 22:50:33 -05:00
|
|
|
//==================================================
|
|
|
|
// List available XRandR entries
|
|
|
|
//==================================================
|
|
|
|
if (cli->has("list-monitors")) {
|
|
|
|
for (auto&& mon : randr_util::get_monitors(conn, conn.root(), true)) {
|
|
|
|
if (ENABLE_XRANDR_MONITORS && mon->output == XCB_NONE) {
|
|
|
|
printf("%s: %ix%i+%i+%i (XRandR monitor)\n", mon->name.c_str(), mon->w, mon->h, mon->x, mon->y);
|
|
|
|
} else {
|
|
|
|
printf("%s: %ix%i+%i+%i\n", mon->name.c_str(), mon->w, mon->h, mon->x, mon->y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-12-03 09:46:48 -05:00
|
|
|
//==================================================
|
|
|
|
// Load user configuration
|
|
|
|
//==================================================
|
2016-12-09 05:32:41 -05:00
|
|
|
string confpath;
|
2016-12-03 09:46:48 -05:00
|
|
|
|
2017-01-12 22:50:33 -05:00
|
|
|
// Make sure a bar name is passed in
|
2017-01-19 20:30:05 -05:00
|
|
|
if (!cli->has(1)) {
|
2017-01-12 22:50:33 -05:00
|
|
|
cli->usage();
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
if (cli->has("config")) {
|
2016-12-09 05:32:41 -05:00
|
|
|
confpath = cli->get("config");
|
2016-12-03 09:46:48 -05:00
|
|
|
} else if (env_util::has("XDG_CONFIG_HOME")) {
|
2016-12-09 05:32:41 -05:00
|
|
|
confpath = env_util::get("XDG_CONFIG_HOME") + "/polybar/config";
|
2016-12-03 09:46:48 -05:00
|
|
|
} else if (env_util::has("HOME")) {
|
2016-12-09 05:32:41 -05:00
|
|
|
confpath = env_util::get("HOME") + "/.config/polybar/config";
|
2016-12-03 09:46:48 -05:00
|
|
|
} else {
|
|
|
|
throw application_error("Define configuration using --config=PATH");
|
|
|
|
}
|
|
|
|
|
2017-01-12 22:47:25 -05:00
|
|
|
config::make_type conf{config::make(move(confpath), cli->get(0))};
|
2016-12-09 05:32:41 -05:00
|
|
|
|
2016-12-03 09:46:48 -05:00
|
|
|
//==================================================
|
|
|
|
// Dump requested data
|
|
|
|
//==================================================
|
2016-12-05 14:41:00 -05:00
|
|
|
if (cli->has("dump")) {
|
2017-01-12 21:52:56 -05:00
|
|
|
printf("%s\n", conf.get(conf.section(), cli->get("dump")).c_str());
|
2016-12-19 23:05:43 -05:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
if (cli->has("print-wmname")) {
|
2017-01-12 21:52:56 -05:00
|
|
|
printf("%s\n", bar::make(true)->settings().wmname.c_str());
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2016-12-03 09:46:48 -05:00
|
|
|
|
|
|
|
//==================================================
|
2016-12-05 14:41:00 -05:00
|
|
|
// Create controller and run application
|
2016-12-03 09:46:48 -05:00
|
|
|
//==================================================
|
2016-12-19 23:05:43 -05:00
|
|
|
unique_ptr<ipc> ipc{};
|
|
|
|
unique_ptr<inotify_watch> config_watch{};
|
2016-12-05 14:41:00 -05:00
|
|
|
|
2016-12-30 17:32:05 -05:00
|
|
|
if (conf.get(conf.section(), "enable-ipc", false)) {
|
2016-12-19 23:05:43 -05:00
|
|
|
ipc = ipc::make();
|
2016-12-03 09:46:48 -05:00
|
|
|
}
|
2016-12-19 23:05:43 -05:00
|
|
|
if (cli->has("reload")) {
|
|
|
|
config_watch = inotify_util::make_watch(conf.filepath());
|
2016-06-14 23:32:35 -04:00
|
|
|
}
|
2016-12-03 09:46:48 -05:00
|
|
|
|
2016-12-19 23:05:43 -05:00
|
|
|
auto ctrl = controller::make(move(ipc), move(config_watch));
|
2016-12-05 14:41:00 -05:00
|
|
|
|
2016-12-19 23:05:43 -05:00
|
|
|
if (!ctrl->run(cli->has("stdout"))) {
|
2016-12-03 09:46:48 -05:00
|
|
|
reload = true;
|
|
|
|
}
|
|
|
|
} catch (const exception& err) {
|
|
|
|
logger.err(err.what());
|
|
|
|
exit_code = EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2016-12-19 23:05:43 -05:00
|
|
|
logger.info("Waiting for spawned processes to end");
|
2016-12-21 02:00:09 -05:00
|
|
|
while (process_util::notify_childprocess()) {
|
2016-12-19 23:05:43 -05:00
|
|
|
;
|
2016-12-21 02:00:09 -05:00
|
|
|
}
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-12-19 23:05:43 -05:00
|
|
|
if (reload) {
|
2016-12-09 06:43:31 -05:00
|
|
|
logger.info("Re-launching application...");
|
|
|
|
process_util::exec(move(argv[0]), move(argv));
|
2016-12-03 09:46:48 -05:00
|
|
|
}
|
2016-11-25 02:42:31 -05:00
|
|
|
|
2016-12-19 23:05:43 -05:00
|
|
|
logger.info("Reached end of application...");
|
|
|
|
return exit_code;
|
2016-06-14 23:32:35 -04:00
|
|
|
}
|