packaging
This commit is contained in:
parent
b30a695ffc
commit
4736b8a462
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
compile_commands.json
|
compile_commands.json
|
||||||
build
|
build
|
||||||
.cache
|
.cache
|
||||||
|
src/config.hpp
|
||||||
|
41
README.md
41
README.md
@ -1,33 +1,58 @@
|
|||||||
# somebar - dwl-like bar for dwm
|
# somebar - dwl-like bar for dwm
|
||||||
|
|
||||||
This is extremely work in progress.
|
![Screenshot](screenshot.png)
|
||||||
|
|
||||||
|
This project is rather new. Beware of bugs.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
* c++ compiler, meson, and ninja
|
* c++ compiler, meson, and ninja
|
||||||
* Qt 5 GUI
|
|
||||||
* libwayland
|
|
||||||
* wayland-scanner
|
* wayland-scanner
|
||||||
|
* libwayland-client
|
||||||
|
* libwayland-cursor
|
||||||
|
* libcairo
|
||||||
|
* libpango
|
||||||
|
* libpangocairo
|
||||||
|
|
||||||
sudo apt install build-essential meson ninja qtbase5-dev libqt5core5a libqt5gui5 \
|
```
|
||||||
libwayland-bin libwayland-client0 libwayland-cursor0 libwayland-dev
|
sudo apt install build-essential meson ninja \
|
||||||
|
libwayland-bin libwayland-client0 libwayland-cursor0 libwayland-dev \
|
||||||
|
libcairo2 libcairo2-dev \
|
||||||
|
libpango-1.0-0 libpango1.0-dev libpangocairo-1.0-0
|
||||||
|
```
|
||||||
|
|
||||||
dwl must have the [wayland-ipc patch](https://gitlab.com/raphaelr/dwl/-/raw/master/patches/wayland-ipc.patch) applied,
|
**dwl must have the [wayland-ipc patch](https://gitlab.com/raphaelr/dwl/-/raw/master/patches/wayland-ipc.patch) applied**,
|
||||||
since that's how the bar communicates with dwl.
|
since that's how the bar communicates with dwl.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
src/config.hpp
|
Copy `src/config.def.hpp` to `src/config.hpp`, and adjust if needed.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
meson setup build
|
meson setup build
|
||||||
ninja -C build
|
ninja -C build
|
||||||
|
./build/somebar
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
somebar doesn't use dwl's status feature. You can start somebar using dwl's `-s` option,
|
somebar doesn't use dwl's status feature. You can start somebar using dwl's `-s` option,
|
||||||
but if you do, close stdout.
|
but if you do, close stdin, as somebar will not read from it.
|
||||||
|
|
||||||
|
Somebar can be controlled by writing to `$XDG_RUNTIME_DIR/somebar-0`. The following
|
||||||
|
commands are supported:
|
||||||
|
|
||||||
|
* `status TEXT`: Updates the status bar
|
||||||
|
* `hide MONITOR` Hides somebar on the specified monitor
|
||||||
|
* `shows MONITOR` Shows somebar on the specified monitor
|
||||||
|
* `toggle MONITOR` Toggles somebar on the specified monitor
|
||||||
|
|
||||||
|
MONITOR is an zxdg_output_v1 name, which can be determined e.g. using `weston-info`.
|
||||||
|
Additionally, MONITOR can be `all` (all monitors) or `selected` (the monitor with focus).
|
||||||
|
|
||||||
|
Commands can be sent either by writing to the file name above, or equivalently by calling
|
||||||
|
somebar with the `-c` argument. For example: `somebar -c toggle all`. This is recommended
|
||||||
|
for shell scripts, as there is no race-free way to write to a file only if it exists.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
project('somebar', ['c', 'cpp'],
|
project('somebar', ['c', 'cpp'],
|
||||||
default_options: ['cpp_std=c++17', 'cpp_args=-Wno-parentheses'])
|
version: '0.1.0',
|
||||||
|
default_options: [
|
||||||
|
'cpp_std=c++17',
|
||||||
|
'cpp_args=-Wno-parentheses',
|
||||||
|
])
|
||||||
|
|
||||||
wayland_dep = dependency('wayland-client')
|
wayland_dep = dependency('wayland-client')
|
||||||
wayland_cursor_dep = dependency('wayland-cursor')
|
wayland_cursor_dep = dependency('wayland-cursor')
|
||||||
@ -20,4 +24,5 @@ executable('somebar',
|
|||||||
cairo_dep,
|
cairo_dep,
|
||||||
pango_dep,
|
pango_dep,
|
||||||
pangocairo_dep,
|
pangocairo_dep,
|
||||||
])
|
],
|
||||||
|
cpp_args: '-DSOMEBAR_VERSION="@0@"'.format(meson.project_version()))
|
||||||
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
@ -22,5 +22,5 @@ constexpr Button buttons[] = {
|
|||||||
{ ClkTagBar, BTN_MIDDLE, toggletag, {0} },
|
{ ClkTagBar, BTN_MIDDLE, toggletag, {0} },
|
||||||
{ ClkLayoutSymbol, BTN_LEFT, setlayout, {.ui = 0} },
|
{ ClkLayoutSymbol, BTN_LEFT, setlayout, {.ui = 0} },
|
||||||
{ ClkLayoutSymbol, BTN_RIGHT, setlayout, {.ui = 2} },
|
{ ClkLayoutSymbol, BTN_RIGHT, setlayout, {.ui = 2} },
|
||||||
{ ClkWinTitle, BTN_RIGHT, spawn, {.v = termcmd} },
|
{ ClkStatusText, BTN_RIGHT, spawn, {.v = termcmd} },
|
||||||
};
|
};
|
||||||
|
81
src/main.cpp
81
src/main.cpp
@ -24,6 +24,7 @@
|
|||||||
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
|
#include "net-tapesoftware-dwl-wm-unstable-v1-client-protocol.h"
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
#include "line_buffer.hpp"
|
||||||
|
|
||||||
struct Monitor {
|
struct Monitor {
|
||||||
uint32_t registryName;
|
uint32_t registryName;
|
||||||
@ -101,7 +102,7 @@ void toggletag(Monitor &m, const Arg &arg)
|
|||||||
}
|
}
|
||||||
void spawn(Monitor&, const Arg &arg)
|
void spawn(Monitor&, const Arg &arg)
|
||||||
{
|
{
|
||||||
if (fork()) {
|
if (fork() == 0) {
|
||||||
auto argv = static_cast<char* const*>(arg.v);
|
auto argv = static_cast<char* const*>(arg.v);
|
||||||
setsid();
|
setsid();
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
@ -334,29 +335,31 @@ static void updateVisibility(const std::string &name, T updater)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LineBuffer<512> _statusBuffer;
|
||||||
static void onStatus()
|
static void onStatus()
|
||||||
{
|
{
|
||||||
// this doesn't handle cases where there's multiple or partial lines in the buffer
|
_statusBuffer.readLines(
|
||||||
char buffer[512];
|
[](void *p, size_t size) {
|
||||||
auto n = read(statusFifoFd, buffer, sizeof(buffer));
|
return read(statusFifoFd, p, size);
|
||||||
auto str = std::string {buffer, (unsigned long) n};
|
},
|
||||||
auto trailer = str.rfind('\n');
|
[](const char *buffer, size_t n) {
|
||||||
if (trailer != std::string::npos) str.erase(trailer);
|
auto str = std::string {buffer, n};
|
||||||
if (str.rfind(prefixStatus, 0) == 0) {
|
if (str.rfind(prefixStatus, 0) == 0) {
|
||||||
lastStatus = str.substr(prefixStatus.size());
|
lastStatus = str.substr(prefixStatus.size());
|
||||||
for (auto &monitor : monitors) {
|
for (auto &monitor : monitors) {
|
||||||
if (monitor.bar) {
|
if (monitor.bar) {
|
||||||
monitor.bar->setStatus(lastStatus);
|
monitor.bar->setStatus(lastStatus);
|
||||||
monitor.bar->invalidate();
|
monitor.bar->invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (str.rfind(prefixShow, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; });
|
||||||
|
} else if (str.rfind(prefixHide, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixHide.size()), [](bool) { return false; });
|
||||||
|
} else if (str.rfind(prefixToggle, 0) == 0) {
|
||||||
|
updateVisibility(str.substr(prefixToggle.size()), [](bool vis) { return !vis; });
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
} else if (str.rfind(prefixShow, 0) == 0) {
|
|
||||||
updateVisibility(str.substr(prefixShow.size()), [](bool) { return true; });
|
|
||||||
} else if (str.rfind(prefixHide, 0) == 0) {
|
|
||||||
updateVisibility(str.substr(prefixHide.size()), [](bool) { return false; });
|
|
||||||
} else if (str.rfind(prefixToggle, 0) == 0) {
|
|
||||||
updateVisibility(str.substr(prefixToggle.size()), [](bool vis) { return !vis; });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HandleGlobalHelper {
|
struct HandleGlobalHelper {
|
||||||
@ -411,6 +414,41 @@ static const struct wl_registry_listener registry_listener = {
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int opt;
|
||||||
|
while ((opt = getopt(argc, argv, "chv")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'h':
|
||||||
|
printf("Usage: %s [-h] [-v] [-c command]\n", argv[0]);
|
||||||
|
printf(" -h: Show this help\n");
|
||||||
|
printf(" -v: Show somebar version\n");
|
||||||
|
printf(" -c: Sends a command to sombar. See README for details.\n");
|
||||||
|
printf("If any of these are specified, somebar exits after the action.\n");
|
||||||
|
printf("Otherwise, somebar will display itself.\n");
|
||||||
|
exit(0);
|
||||||
|
case 'v':
|
||||||
|
printf("somebar " SOMEBAR_VERSION "\n");
|
||||||
|
exit(0);
|
||||||
|
case 'c':
|
||||||
|
if (optind >= argc) {
|
||||||
|
die("Expected command");
|
||||||
|
}
|
||||||
|
auto path = std::string {getenv("XDG_RUNTIME_DIR")} + "/somebar-0";
|
||||||
|
int fd = open(path.c_str(), O_WRONLY | O_CLOEXEC);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr, "could not open %s: ", path.c_str());
|
||||||
|
perror("");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
auto str = std::string {};
|
||||||
|
for (auto i = optind; i<argc; i++) {
|
||||||
|
if (i > optind) str += " ";
|
||||||
|
str += argv[i];
|
||||||
|
}
|
||||||
|
str += "\n";
|
||||||
|
write(fd, str.c_str(), str.size());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
static sigset_t blockedsigs;
|
static sigset_t blockedsigs;
|
||||||
sigemptyset(&blockedsigs);
|
sigemptyset(&blockedsigs);
|
||||||
sigaddset(&blockedsigs, SIGINT);
|
sigaddset(&blockedsigs, SIGINT);
|
||||||
@ -506,6 +544,7 @@ void waylandFlush()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void die(const char *why) {
|
void die(const char *why) {
|
||||||
|
fprintf(stderr, "%s\n", why);
|
||||||
cleanup();
|
cleanup();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user