Compare commits

...

47 Commits
0.1.2 ... 0.2.0

Author SHA1 Message Date
43cd80fb31 chore: 0.2.0 2018-11-03 13:20:05 +01:00
5ece0d98ee Merge pull request #78 from mithodin/filesystem-experimental
add option for when filesystem still lives in the experimental namespace
2018-11-03 13:00:04 +01:00
0637888460 even simpler check 2018-11-03 12:44:15 +01:00
ebbdaa168c automatically detect where filesystem lives 2018-11-02 23:15:42 +01:00
6ab01b1ad4 fix(style): not charging 2018-11-02 23:00:38 +01:00
cf921a5e14 Merge pull request #76 from mithodin/charging-full
Add class for full battery and give option to interpret unknown as full
2018-11-02 22:51:57 +01:00
25f31b19f6 formatting is hard. 2018-11-02 22:50:01 +01:00
d8b6201632 ...and fix the function signature in the header 2018-11-02 22:15:54 +01:00
123ce083b4 fix typo and initialize old_status_ 2018-11-02 22:08:55 +01:00
0522577fe5 make status and state fully configurable formats 2018-11-02 22:04:43 +01:00
1ff9fd06af Merge pull request #77 from mithodin/old-gdbus-codegen
fix compilation on systems with old gdbus-codegen
2018-11-02 21:23:10 +01:00
b6cad05489 fix formatting 2018-11-02 21:13:57 +01:00
236be90c2f add option for when filesystem still lives in the experimental namespace 2018-11-02 20:59:41 +01:00
f137090d55 fix compilation on systems with old gdbus-codegen 2018-11-02 20:13:09 +01:00
9c57df505c Add class for full battery and give option to interpret unknown as full 2018-11-02 19:41:00 +01:00
00e7e87f55 fix: style 2018-11-02 17:39:00 +01:00
836c543c62 fix: style 2018-11-02 17:07:51 +01:00
7bca5fd6bd feat(Bar): add a warning about minimum height 2018-11-02 12:35:26 +01:00
61e9f0803d Merge pull request #75 from ForTheReallys/proper_height
Fix #54
2018-11-02 12:26:14 +01:00
9b201c77d7 feat: battery states && format-full/charging 2018-11-02 11:23:29 +01:00
4b68840212 Fix #54 2018-11-01 16:00:38 -05:00
9d4048983d refactor: remove useless tmp variable 2018-11-01 09:27:00 +01:00
0670225e69 Merge pull request #72 from Robinhuett/custom_module_states
Custom modules can control tooltip and CSS class
2018-11-01 09:11:15 +01:00
e23fbd0add Added return-type json to custom module 2018-11-01 00:40:44 +01:00
341d3300fa Custom modules can control tooltip and CSS class 2018-10-30 21:28:31 +01:00
c3e185546d Merge pull request #68 from harishkrupo/master
Add configuration options for widgets on mouse events
2018-10-30 16:32:37 +01:00
0e93de9c0a Merge pull request #71 from Robinhuett/configurable_battery_levels
Added second warning stage to battery module
2018-10-30 16:31:01 +01:00
3e34137ac7 pulseaudio: Change volume on scroll event
Subscribe for mouse scroll events on the pulseaudio widget
and change volume when event is received.
Scroll up increments the volume and scroll down decrements it.
These events are only subscibed when there are no user defined
commands present for them.

Signed-off-by: Harish Krupo <harishkrupo@gmail.com>
2018-10-30 20:53:43 +05:30
4c8621c7a5 Added second warning stage to battery module
Also naming is a bit more consistent
2018-10-30 16:23:36 +01:00
d7d1ebd736 ALabel: Add support for configurable mouse events
This patch adds 3 new configuration options applicable for
subclasses of ALabel. The options can be used to execute
user defined code in response to the 3 mouse events:
* on-click: The left mouse button click
* on-scroll-up
* on-scroll-down
This patch also modifies the behaviour of the format-alt toggle
such that when the on-click event is configured, format-alt is
toggled on any mouse click other than left click. When on-click
is not defined, any mouse button would toggle format-alt.

Signed-off-by: Harish Krupo <harishkrupo@gmail.com>
2018-10-30 20:52:23 +05:30
e93c5e7957 Merge pull request #70 from Robinhuett/mode_module
Add module to show sway binding mode
2018-10-30 14:26:43 +01:00
668b7b736c Added default config for sway binding mode 2018-10-30 13:44:44 +01:00
a042eea384 Add module to show sway binding mode 2018-10-30 13:39:30 +01:00
c9a8a07976 fix(window): title on new workspace 2018-10-29 21:52:53 +01:00
4307e4fd8e chore: upgrade fmt to 5.2.0 2018-10-28 14:40:25 +01:00
daf613f8ca feat: add debug about tray beta 2018-10-28 08:43:48 +01:00
3f2eb0b492 chore: 0.1.3 2018-10-28 08:39:33 +01:00
4f773ea268 Merge pull request #65 from maxice8/fix-musl
add missing <cstring> include for strncpy, fixes musl
2018-10-28 08:29:56 +01:00
047473e5a4 add missing <cstring> include for strncpy, fixes musl
I/usr/include/libdbusmenu-glib-0.4 -flto -fdiagnostics-color=always -DNDEBUG -pipe -D_FILE_OFFSET_BITS=64 -std=c++17 -DHAVE_SWAY -DHAVE_LIBPULSE -DHAVE_DBUSMENU -D_FORTIFY_SOURCE=2 -mtune=generic -O2 -D_REENTRANT -pthread  -MD -MQ 'waybar@exe/src_modules_sway_ipc_client.cpp.o' -MF 'waybar@exe/src_modules_sway_ipc_client.cpp.o.d' -o 'waybar@exe/src_modules_sway_ipc_client.cpp.o' -c ../src/modules/sway/ipc/client.cpp
../src/modules/sway/ipc/client.cpp: In member function 'int waybar::modules::sway::Ipc::open(const string&) const':
../src/modules/sway/ipc/client.cpp:47:3: error: 'strncpy' was not declared in this scope
   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
   ^~~~~~~
../src/modules/sway/ipc/client.cpp:47:3: note: 'strncpy' is defined in header '<cstring>'; did you forget to '#include <cstring>'?
../src/modules/sway/ipc/client.cpp:2:1:
+#include <cstring>

../src/modules/sway/ipc/client.cpp:47:3:
   strncpy(addr.sun_path, socketPath.c_str(), sizeof(addr.sun_path) - 1);
   ^~~~~~~
[36/44] Compiling C++ object 'waybar@exe/src_modules_custom.cpp.o'.
[37/44] Compiling C++ object 'waybar@exe/src_client.cpp.o'.
[38/44] Compiling C++ object 'waybar@exe/src_modules_cpu.cpp.o'.
ninja: build stopped: subcommand failed.
2018-10-28 04:06:07 -03:00
ed3e4b1395 fix(pulseaudio): check active_port is set 2018-10-27 11:23:43 +02:00
16b01e1059 Merge pull request #62 from colemickens/giounix20
meson: fix 'gio-unix-2.0' dependency
2018-10-27 09:35:47 +02:00
1ae490c8f7 Merge pull request #61 from colemickens/outdir
meson: make extra output directory configurable
2018-10-27 09:16:11 +02:00
0d0a3be483 meson: fix 'gio-unix-2.0' dependency 2018-10-26 23:21:03 -07:00
a1c4b9bb0c meson: make extra output directory configurable 2018-10-26 23:20:38 -07:00
a55a1ae866 fix(tray): icons size 2018-10-26 14:53:39 +02:00
07d8dfb3d6 feat(tray): spacing config 2018-10-26 12:08:50 +02:00
5010227e6b fix(tray): icons 2018-10-26 11:59:03 +02:00
29 changed files with 610 additions and 162 deletions

2
.gitignore vendored
View File

@ -4,7 +4,7 @@ vgcore.*
/.vscode
*.swp
packagecache
/subprojects/fmt-4.1.0
/subprojects/**/
/build
/dist
/meson.egg-info

View File

@ -6,21 +6,25 @@
namespace waybar {
class ALabel : public IModule {
public:
ALabel(const Json::Value&, const std::string format);
virtual ~ALabel() = default;
virtual auto update() -> void;
virtual std::string getIcon(uint16_t, const std::string& alt = "");
virtual operator Gtk::Widget &();
protected:
Gtk::EventBox event_box_;
Gtk::Label label_;
const Json::Value& config_;
std::string format_;
private:
bool handleToggle(GdkEventButton* const& ev);
bool alt = false;
const std::string default_format_;
public:
ALabel(const Json::Value&, const std::string format);
virtual ~ALabel() = default;
virtual auto update() -> void;
virtual std::string getIcon(uint16_t, const std::string& alt = "");
virtual operator Gtk::Widget&();
protected:
Gtk::EventBox event_box_;
Gtk::Label label_;
const Json::Value& config_;
std::string format_;
std::mutex mutex_;
private:
bool handleToggle(GdkEventButton* const& ev);
bool handleScroll(GdkEventScroll*);
bool alt = false;
const std::string default_format_;
};
}
} // namespace waybar

View File

@ -3,6 +3,7 @@
#include <json/json.h>
#include "modules/clock.hpp"
#ifdef HAVE_SWAY
#include "modules/sway/mode.hpp"
#include "modules/sway/workspaces.hpp"
#include "modules/sway/window.hpp"
#endif

View File

@ -1,6 +1,10 @@
#pragma once
#include <filesystem>
#ifdef FILESYSTEM_EXPERIMENTAL
#include <experimental/filesystem>
#else
#include <filesystem>
#endif
#include <fstream>
#include <iostream>
#include <fmt/format.h>
@ -11,7 +15,11 @@
namespace waybar::modules {
#ifdef FILESYSTEM_EXPERIMENTAL
namespace fs = std::experimental::filesystem;
#else
namespace fs = std::filesystem;
#endif
class Battery : public ALabel {
public:
@ -22,11 +30,14 @@ class Battery : public ALabel {
static inline const fs::path data_dir_ = "/sys/class/power_supply/";
void worker();
std::tuple<uint16_t, std::string> getInfos();
std::string getState(uint16_t);
util::SleeperThread thread_;
util::SleeperThread threadTimer_;
std::vector<fs::path> batteries_;
int fd_;
std::string old_status_;
};
}

View File

@ -4,6 +4,7 @@
#include <iostream>
#include "util/chrono.hpp"
#include "util/command.hpp"
#include "util/json.hpp"
#include "ALabel.hpp"
namespace waybar::modules {
@ -15,10 +16,17 @@ class Custom : public ALabel {
private:
void delayWorker();
void continuousWorker();
void parseOutputRaw();
void parseOutputJson();
const std::string name_;
std::string text_;
std::string tooltip_;
std::string class_;
std::string prevclass_;
waybar::util::SleeperThread thread_;
waybar::util::command::res output_;
waybar::util::JsonParser parser_;
};
}

View File

@ -1,7 +1,8 @@
#pragma once
#include <pulse/pulseaudio.h>
#include <fmt/format.h>
#include <pulse/pulseaudio.h>
#include <pulse/volume.h>
#include <algorithm>
#include "ALabel.hpp"
@ -18,6 +19,8 @@ class Pulseaudio : public ALabel {
static void contextStateCb(pa_context*, void*);
static void sinkInfoCb(pa_context*, const pa_sink_info*, int, void*);
static void serverInfoCb(pa_context*, const pa_server_info*, void*);
static void volumeModifyCb(pa_context*, int, void*);
bool handleScroll(GdkEventScroll* e);
const std::string getPortIcon() const;
@ -26,9 +29,11 @@ class Pulseaudio : public ALabel {
pa_context* context_;
uint32_t sink_idx_{0};
uint16_t volume_;
pa_cvolume pa_volume_;
bool muted_;
std::string port_name_;
std::string desc_;
bool scrolling_;
};
}
} // namespace waybar::modules

View File

@ -1,7 +1,7 @@
#pragma once
#include <gtkmm.h>
#include <json/json.h>
#include <tuple>
#include <dbus-status-notifier-watcher.h>
#include "modules/sni/sni.hpp"
@ -10,7 +10,7 @@ namespace waybar::modules::SNI {
class Host {
public:
Host(Glib::Dispatcher*);
Host(Glib::Dispatcher*, const Json::Value&);
std::vector<Item> items;
private:
static void busAcquired(GDBusConnection*, const gchar*, gpointer);
@ -32,6 +32,7 @@ class Host {
Glib::Dispatcher* dp_;
GCancellable* cancellable_ = nullptr;
SnWatcher* watcher_ = nullptr;
const Json::Value &config_;
};
}

View File

@ -2,12 +2,18 @@
#include <dbus-status-notifier-item.h>
#include <gtkmm.h>
#include <json/json.h>
#ifdef FILESYSTEM_EXPERIMENTAL
#include <experimental/filesystem>
#else
#include <filesystem>
#endif
namespace waybar::modules::SNI {
class Item {
public:
Item(std::string, std::string, Glib::Dispatcher *);
Item(std::string, std::string, Glib::Dispatcher*, Json::Value);
std::string bus_name;
std::string object_path;
@ -39,6 +45,7 @@ private:
static void handleSecondaryActivate(GObject *, GAsyncResult *, gpointer);
void updateImage();
void updateMenu();
Glib::RefPtr<Gdk::Pixbuf> extractPixBuf(GVariant *variant);
Glib::RefPtr<Gdk::Pixbuf> getIconByName(std::string name, int size);
bool handleClick(GdkEventButton *const & /*ev*/);
@ -46,6 +53,7 @@ private:
Glib::Dispatcher *dp_;
GCancellable *cancellable_ = nullptr;
SnItem *proxy_ = nullptr;
Json::Value config_;
};
} // namespace waybar::modules::SNI

View File

@ -1,6 +1,7 @@
#pragma once
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>

View File

@ -0,0 +1,27 @@
#pragma once
#include <fmt/format.h>
#include "bar.hpp"
#include "client.hpp"
#include "util/chrono.hpp"
#include "util/json.hpp"
#include "ALabel.hpp"
#include "modules/sway/ipc/client.hpp"
namespace waybar::modules::sway {
class Mode : public ALabel {
public:
Mode(waybar::Bar&, const Json::Value&);
auto update() -> void;
private:
void worker();
Bar& bar_;
waybar::util::SleeperThread thread_;
util::JsonParser parser_;
Ipc ipc_;
std::string mode_;
};
}

View File

@ -29,7 +29,23 @@ inline struct res exec(const std::string cmd)
output.erase(output.length()-1);
}
int exit_code = WEXITSTATUS(pclose(fp));
return { exit_code, output };
return {exit_code, output};
}
inline bool forkExec(std::string cmd) {
if (cmd == "") return true;
int32_t pid = fork();
if (pid < 0) {
printf("Unable to exec cmd %s, error %s", cmd.c_str(), strerror(errno));
return false;
}
// Child executes the command
if (!pid) execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)0);
return true;
}
} // namespace waybar::util::command

View File

@ -1,6 +1,6 @@
project(
'waybar', 'cpp', 'c',
version: '0.1.2',
version: '0.2.0',
license: 'MIT',
default_options : [
'cpp_std=c++17',
@ -33,6 +33,7 @@ wayland_protos = dependency('wayland-protocols')
wlroots = dependency('wlroots', fallback: ['wlroots', 'wlroots'])
gtkmm = dependency('gtkmm-3.0')
dbusmenu_gtk = dependency('dbusmenu-gtk3-0.4', required: get_option('dbusmenu-gtk'))
giounix = dependency('gio-unix-2.0', required: get_option('dbusmenu-gtk'))
jsoncpp = dependency('jsoncpp')
sigcpp = dependency('sigc++-2.0')
libnl = dependency('libnl-3.0', required: get_option('libnl'))
@ -56,6 +57,7 @@ if find_program('sway', required : false).found()
add_project_arguments('-DHAVE_SWAY', language: 'cpp')
src_files += [
'src/modules/sway/ipc/client.cpp',
'src/modules/sway/mode.cpp',
'src/modules/sway/window.cpp',
'src/modules/sway/workspaces.cpp'
]
@ -81,6 +83,12 @@ if dbusmenu_gtk.found()
)
endif
compiler = meson.get_compiler('cpp')
if not compiler.has_header('filesystem')
add_project_arguments('-DFILESYSTEM_EXPERIMENTAL', language: 'cpp')
endif
subdir('protocol')
executable(
@ -98,6 +106,7 @@ executable(
wayland_cursor,
gtkmm,
dbusmenu_gtk,
giounix,
libnl,
libnlgen,
libpulse
@ -109,7 +118,7 @@ executable(
install_data(
'./resources/config',
'./resources/style.css',
install_dir: '/etc/xdg/waybar',
install_dir: join_paths(get_option('out'), 'etc/xdg/waybar')
)
clangtidy = find_program('clang-tidy', required: false)

View File

@ -1,3 +1,4 @@
option('libnl', type: 'feature', value: 'auto', description: 'Enable libnl support for network related features')
option('pulseaudio', type: 'feature', value: 'auto', description: 'Enable support for pulseaudio')
option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray')
option('dbusmenu-gtk', type: 'feature', value: 'auto', description: 'Enable support for tray')
option('out', type: 'string', value : '/', description: 'output prefix directory')

View File

@ -38,31 +38,63 @@ endforeach
gdbus_codegen = find_program('gdbus-codegen')
gdbus_code = generator(
gdbus_codegen,
output: '@BASENAME@.c',
arguments: ['--c-namespace', 'Sn', '--body', '--output', '@OUTPUT@', '@INPUT@']
)
r = run_command(gdbus_codegen, '--body', '--output', '/dev/null')
if r.returncode() != 0
gdbus_code_dsnw = custom_target(
'dbus-status-notifier-watcher.[ch]',
output: ['@BASENAME@.c','@BASENAME@.h'],
input: './dbus-status-notifier-watcher.xml',
command: [gdbus_codegen,'--c-namespace', 'Sn', '--generate-c-code', 'protocol/@BASENAME@', '@INPUT@'],
)
gdbus_header = generator(
gdbus_codegen,
output: '@BASENAME@.h',
arguments: ['--c-namespace', 'Sn', '--header', '--output', '@OUTPUT@', '@INPUT@']
)
gdbus_code_dsni = custom_target(
'dbus-status-notifier-item.[ch]',
output: ['@BASENAME@.c','@BASENAME@.h'],
input: './dbus-status-notifier-item.xml',
command: [gdbus_codegen,'--c-namespace', 'Sn', '--generate-c-code', 'protocol/@BASENAME@', '@INPUT@'],
)
client_protos_src += gdbus_code.process('./dbus-status-notifier-watcher.xml')
client_protos_headers += gdbus_header.process('./dbus-status-notifier-watcher.xml')
gdbus_code_dm = custom_target(
'dbus-menu.[ch]',
output: ['@BASENAME@.c','@BASENAME@.h'],
input: './dbus-menu.xml',
command: [gdbus_codegen,'--c-namespace', 'Sn', '--generate-c-code', 'protocol/@BASENAME@', '@INPUT@'],
)
client_protos_src += gdbus_code.process('./dbus-status-notifier-item.xml')
client_protos_headers += gdbus_header.process('./dbus-status-notifier-item.xml')
client_protos_src += gdbus_code_dsnw[0]
client_protos_headers += gdbus_code_dsnw[1]
client_protos_src += gdbus_code_dsni[0]
client_protos_headers += gdbus_code_dsni[1]
client_protos_src += gdbus_code_dm[0]
client_protos_headers += gdbus_code_dm[1]
else
gdbus_code = generator(
gdbus_codegen,
output: '@BASENAME@.c',
arguments: ['--c-namespace', 'Sn', '--body', '--output', '@OUTPUT@', '@INPUT@']
)
gdbus_header = generator(
gdbus_codegen,
output: '@BASENAME@.h',
arguments: ['--c-namespace', 'Sn', '--header', '--output', '@OUTPUT@', '@INPUT@']
)
client_protos_src += gdbus_code.process('./dbus-status-notifier-watcher.xml')
client_protos_headers += gdbus_header.process('./dbus-status-notifier-watcher.xml')
client_protos_src += gdbus_code.process('./dbus-status-notifier-item.xml')
client_protos_headers += gdbus_header.process('./dbus-status-notifier-item.xml')
client_protos_src += gdbus_code.process('./dbus-menu.xml')
client_protos_headers += gdbus_header.process('./dbus-menu.xml')
endif
client_protos_src += gdbus_code.process('./dbus-menu.xml')
client_protos_headers += gdbus_header.process('./dbus-menu.xml')
lib_client_protos = static_library(
'client_protos',
client_protos_src + client_protos_headers,
dependencies: [wayland_client, gtkmm],
dependencies: [wayland_client, gtkmm, giounix],
include_directories: include_directories('..'),
) # for the include directory

View File

@ -4,7 +4,7 @@
// "height": 30, // Waybar height
// "width": 1280, // Waybar width
// Choose the order of the modules
"modules-left": ["sway/workspaces", "custom/spotify"],
"modules-left": ["sway/workspaces", "sway/mode", "custom/spotify"],
"modules-center": ["sway/window"],
"modules-right": ["pulseaudio", "network", "cpu", "memory", "battery", "battery#bat2", "clock", "tray"],
// Modules configuration
@ -23,9 +23,16 @@
// "default": ""
// }
// },
"sway/mode": {
"format": "{}"
},
"sway/window": {
"max-length": 50
},
"tray": {
// "icon-size": 21,
"spacing": 10
},
"clock": {
"format-alt": "{:%Y-%m-%d}"
},
@ -36,7 +43,14 @@
"format": "{}% "
},
"battery": {
"states": {
// "good": 95,
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
// "format-good": "", // An empty format will hide the module
// "format-full": "",
"format-icons": ["", "", "", "", ""]
},
"battery#bat2": {
@ -60,13 +74,14 @@
"portable": "",
"car": "",
"default": ["", ""]
}
},
"on-click": "pavucontrol"
},
"custom/spotify": {
"format": " {}",
"max-length": 40,
"interval": 30, // Remove this if your script is endless and write in loop
"exec": "$HOME/.config/waybar/mediaplayer.sh", // Script in resources folder
"exec": "$HOME/.config/waybar/mediaplayer.sh 2> /dev/null", // Script in resources folder
"exec-if": "pgrep spotify"
}
}

View File

@ -3,6 +3,7 @@
border-radius: 0;
font-family: Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
min-height: 0;
}
window#waybar {
@ -23,7 +24,12 @@ window#waybar {
border-bottom: 3px solid white;
}
#clock, #battery, #cpu, #memory, #network, #pulseaudio, #custom-spotify, #tray {
#mode {
background: #64727D;
border-bottom: 3px solid white;
}
#clock, #battery, #cpu, #memory, #network, #pulseaudio, #custom-spotify, #tray, #mode {
padding: 0 10px;
margin: 0 5px;
}
@ -49,7 +55,7 @@ window#waybar {
}
}
#battery.warning {
#battery.warning:not(.charging) {
background: #f53c3c;
color: white;
animation-name: blink;

View File

@ -1,4 +1,5 @@
#include "ALabel.hpp"
#include <util/command.hpp>
#include <iostream>
@ -14,30 +15,81 @@ waybar::ALabel::ALabel(const Json::Value& config, const std::string format)
}
if (config_["format-alt"].isString()) {
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event()
.connect(sigc::mem_fun(*this, &ALabel::handleToggle));
event_box_.signal_button_press_event().connect(
sigc::mem_fun(*this, &ALabel::handleToggle));
}
// configure events' user commands
if (config_["on-click"].isString()) {
event_box_.add_events(Gdk::BUTTON_PRESS_MASK);
event_box_.signal_button_press_event().connect(
sigc::mem_fun(*this, &ALabel::handleToggle));
}
if (config_["on-scroll-up"].isString()) {
event_box_.add_events(Gdk::SCROLL_MASK);
event_box_.signal_scroll_event().connect(
sigc::mem_fun(*this, &ALabel::handleScroll));
}
if (config_["on-scroll-down"].isString()) {
event_box_.add_events(Gdk::SCROLL_MASK);
event_box_.signal_scroll_event().connect(
sigc::mem_fun(*this, &ALabel::handleScroll));
}
}
auto waybar::ALabel::update() -> void
{
auto waybar::ALabel::update() -> void {
// Nothing here
}
bool waybar::ALabel::handleToggle(GdkEventButton* const& /*ev*/)
{
alt = !alt;
if (alt) {
format_ = config_["format-alt"].asString();
bool waybar::ALabel::handleToggle(GdkEventButton* const& e) {
if (config_["on-click"].isString() && e->button == 1) {
waybar::util::command::forkExec(config_["on-click"].asString());
} else {
format_ = default_format_;
alt = !alt;
if (alt) {
format_ = config_["format-alt"].asString();
} else {
format_ = default_format_;
}
}
dp.emit();
return true;
}
bool waybar::ALabel::handleScroll(GdkEventScroll* e) {
// Avoid concurrent scroll event
std::lock_guard<std::mutex> lock(mutex_);
bool direction_up = false;
if (e->direction == GDK_SCROLL_UP) {
direction_up = true;
}
if (e->direction == GDK_SCROLL_DOWN) {
direction_up = false;
}
if (e->direction == GDK_SCROLL_SMOOTH) {
gdouble delta_x, delta_y;
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent*>(e),
&delta_x, &delta_y);
if (delta_y < 0) {
direction_up = true;
} else if (delta_y > 0) {
direction_up = false;
}
}
if (direction_up && config_["on-scroll-up"].isString()) {
waybar::util::command::forkExec(config_["on-scroll-up"].asString());
} else if (config_["on-scroll-down"].isString()) {
waybar::util::command::forkExec(config_["on-scroll-down"].asString());
}
dp.emit();
return true;
}
std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt)
{
std::string waybar::ALabel::getIcon(uint16_t percentage,
const std::string& alt) {
auto format_icons = config_["format-icons"];
if (format_icons.isObject()) {
if (!alt.empty() && format_icons[alt].isString()) {
@ -57,6 +109,4 @@ std::string waybar::ALabel::getIcon(uint16_t percentage, const std::string& alt)
return "";
}
waybar::ALabel::operator Gtk::Widget &() {
return event_box_;
}
waybar::ALabel::operator Gtk::Widget&() { return event_box_; }

View File

@ -20,16 +20,15 @@ waybar::Bar::Bar(const Client& client,
zxdg_output_manager_v1_get_xdg_output(client.xdg_output_manager, *output);
zxdg_output_v1_add_listener(xdg_output_, &xdgOutputListener, this);
window.set_title("waybar");
window.set_decorated(false);
window.set_name("waybar");
window.set_decorated(false);
window.set_resizable(false);
setupConfig();
setupCss();
setupWidgets();
Gtk::Widget& wrap(window);
gtk_widget_realize(wrap.gobj());
GdkWindow *gdk_window = gtk_widget_get_window(wrap.gobj());
auto wrap = reinterpret_cast<GtkWidget*>(window.gobj());
gtk_widget_realize(wrap);
GdkWindow *gdk_window = gtk_widget_get_window(wrap);
gdk_wayland_window_set_use_custom_surface(gdk_window);
surface = gdk_wayland_window_get_wl_surface(gdk_window);
@ -60,6 +59,8 @@ waybar::Bar::Bar(const Client& client,
zwlr_layer_surface_v1_set_size(layer_surface, width, height);
wl_surface_commit(surface);
setupWidgets();
}
void waybar::Bar::handleLogicalPosition(void* /*data*/,
@ -104,11 +105,20 @@ void waybar::Bar::layerSurfaceHandleConfigure(void* data,
if (width != o->width_ || height != o->height_) {
o->width_ = width;
o->height_ = height;
o->window.set_size_request(o->width_, o->height_);
o->window.resize(o->width_, o->height_);
int dummy_width, min_height;
o->window.get_size(dummy_width, min_height);
if (o->height_ < static_cast<uint32_t>(min_height)) {
std::cout << fmt::format("Requested height: {} exceeds the minimum \
height: {} required by the modules", o->height_, min_height) << std::endl;
o->height_ = min_height;
}
std::cout << fmt::format(
"Bar configured (width: {}, height: {}) for output: {}",
o->width_, o->height_, o->output_name) << std::endl;
o->window.set_size_request(o->width_, o->height_);
o->window.resize(o->width_, o->height_);
zwlr_layer_surface_v1_set_exclusive_zone(surface, o->height_);
zwlr_layer_surface_v1_set_size(surface, o->width_, o->height_);
wl_surface_commit(o->surface);

View File

@ -12,6 +12,9 @@ waybar::IModule* waybar::Factory::makeModule(const std::string &name) const
return new waybar::modules::Battery(config_[name]);
}
#ifdef HAVE_SWAY
if (ref == "sway/mode") {
return new waybar::modules::sway::Mode(bar_, config_[name]);
}
if (ref == "sway/workspaces") {
return new waybar::modules::sway::Workspaces(bar_, config_[name]);
}

View File

@ -34,7 +34,6 @@ waybar::modules::Battery::Battery(const Json::Value& config)
for (auto const& bat : batteries_) {
inotify_add_watch(fd_, (bat / "uevent").c_str(), IN_ACCESS);
}
label_.set_name("battery");
worker();
}
@ -63,11 +62,11 @@ void waybar::modules::Battery::worker()
};
}
auto waybar::modules::Battery::update() -> void
std::tuple<uint16_t, std::string> waybar::modules::Battery::getInfos()
{
try {
uint16_t total = 0;
std::string status;
std::string status = "Unknown";
for (auto const& bat : batteries_) {
uint16_t capacity;
std::string _status;
@ -79,22 +78,64 @@ auto waybar::modules::Battery::update() -> void
total += capacity;
}
uint16_t capacity = total / batteries_.size();
label_.set_text(fmt::format(format_, fmt::arg("capacity", capacity),
fmt::arg("icon", getIcon(capacity))));
label_.set_tooltip_text(status);
bool charging = status == "Charging";
if (charging) {
label_.get_style_context()->add_class("charging");
} else {
label_.get_style_context()->remove_class("charging");
}
auto critical = config_["critical"].isUInt() ? config_["critical"].asUInt() : 15;
if (capacity <= critical && !charging) {
label_.get_style_context()->add_class("warning");
} else {
label_.get_style_context()->remove_class("warning");
}
return {capacity, status};
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
return {0, "Unknown"};
}
}
std::string waybar::modules::Battery::getState(uint16_t capacity)
{
// Get current state
std::vector<std::pair<std::string, uint16_t>> states;
if (config_["states"].isObject()) {
for (auto it = config_["states"].begin(); it != config_["states"].end(); ++it) {
if (it->isUInt() && it.key().isString()) {
states.push_back({it.key().asString(), it->asUInt()});
}
}
}
// Sort states
std::sort(states.begin(), states.end(), [](auto &a, auto &b) {
return a.second < b.second;
});
std::string validState = "";
for (auto state : states) {
if (capacity <= state.second && validState.empty()) {
label_.get_style_context()->add_class(state.first);
validState = state.first;
} else {
label_.get_style_context()->remove_class(state.first);
}
}
return validState;
}
auto waybar::modules::Battery::update() -> void
{
auto [capacity, status] = getInfos();
label_.set_tooltip_text(status);
std::transform(status.begin(), status.end(), status.begin(), ::tolower);
auto format = format_;
auto state = getState(capacity);
label_.get_style_context()->remove_class(old_status_);
label_.get_style_context()->add_class(status);
old_status_ = status;
if (!state.empty() && config_["format-" + status + "-" + state].isString()) {
format = config_["format-" + status + "-" + state].asString();
} else if (config_["format-" + status].isString()) {
format = config_["format-" + status].asString();
} else if (!state.empty() && config_["format-" + state].isString()) {
format = config_["format-" + state].asString();
}
if (format.empty()) {
event_box_.hide();
label_.set_name("");
} else {
event_box_.show();
label_.set_name("battery");
label_.set_text(fmt::format(format, fmt::arg("capacity", capacity),
fmt::arg("icon", getIcon(capacity))));
}
}

View File

@ -72,9 +72,65 @@ auto waybar::modules::Custom::update() -> void
label_.set_name("");
} else {
label_.set_name("custom-" + name_);
auto str = fmt::format(format_, output_.out);
if (config_["return-type"].asString() == "json") {
parseOutputJson();
} else {
parseOutputRaw();
}
auto str = fmt::format(format_, text_);
label_.set_text(str);
label_.set_tooltip_text(str);
if (text_ == tooltip_) {
label_.set_tooltip_text(str);
} else {
label_.set_tooltip_text(tooltip_);
}
if (class_ != "") {
if (prevclass_ != "") {
label_.get_style_context()->remove_class(prevclass_);
}
label_.get_style_context()->add_class(class_);
prevclass_ = class_;
} else {
label_.get_style_context()->remove_class(prevclass_);
prevclass_ = "";
}
label_.show();
}
}
void waybar::modules::Custom::parseOutputRaw()
{
std::istringstream output(output_.out);
std::string line;
int i = 0;
while (getline(output, line)) {
if (i == 0) {
text_ = line;
tooltip_ = line;
class_ = "";
} else if (i == 1) {
tooltip_ = line;
} else if (i == 2) {
class_ = line;
} else {
break;
}
i++;
}
}
void waybar::modules::Custom::parseOutputJson()
{
std::istringstream output(output_.out);
std::string line;
while (getline(output, line)) {
auto parsed = parser_.parse(line);
text_ = parsed["text"].asString();
tooltip_ = parsed["tooltip"].asString();
class_ = parsed["class"].asString();
break;
}
}

View File

@ -1,9 +1,14 @@
#include "modules/pulseaudio.hpp"
waybar::modules::Pulseaudio::Pulseaudio(const Json::Value& config)
: ALabel(config, "{volume}%"), mainloop_(nullptr), mainloop_api_(nullptr),
context_(nullptr), sink_idx_(0), volume_(0), muted_(false)
{
waybar::modules::Pulseaudio::Pulseaudio(const Json::Value &config)
: ALabel(config, "{volume}%"),
mainloop_(nullptr),
mainloop_api_(nullptr),
context_(nullptr),
sink_idx_(0),
volume_(0),
muted_(false),
scrolling_(false) {
label_.set_name("pulseaudio");
mainloop_ = pa_threaded_mainloop_new();
if (mainloop_ == nullptr) {
@ -26,10 +31,18 @@ waybar::modules::Pulseaudio::Pulseaudio(const Json::Value& config)
throw std::runtime_error("pa_mainloop_run() failed.");
}
pa_threaded_mainloop_unlock(mainloop_);
// define the pulse scroll events only when no user provided
// events are configured
if (!config["on-scroll-up"].isString() &&
!config["on-scroll-down"].isString()) {
event_box_.add_events(Gdk::SCROLL_MASK);
event_box_.signal_scroll_event().connect(
sigc::mem_fun(*this, &Pulseaudio::handleScroll));
}
}
waybar::modules::Pulseaudio::~Pulseaudio()
{
waybar::modules::Pulseaudio::~Pulseaudio() {
mainloop_api_->quit(mainloop_api_, 0);
pa_threaded_mainloop_stop(mainloop_);
pa_threaded_mainloop_free(mainloop_);
@ -58,6 +71,47 @@ void waybar::modules::Pulseaudio::contextStateCb(pa_context *c, void *data)
}
}
bool waybar::modules::Pulseaudio::handleScroll(GdkEventScroll *e) {
// Avoid concurrent scroll event
bool direction_up = false;
// XXX/TODO: Change of 100 corresponds to 1%, does that always hold true?
uint16_t change = 100;
pa_cvolume pa_volume = pa_volume_;
if (scrolling_) {
return false;
}
scrolling_ = true;
if (e->direction == GDK_SCROLL_UP) {
direction_up = true;
}
if (e->direction == GDK_SCROLL_DOWN) {
direction_up = false;
}
if (e->direction == GDK_SCROLL_SMOOTH) {
gdouble delta_x, delta_y;
gdk_event_get_scroll_deltas(reinterpret_cast<const GdkEvent *>(e), &delta_x,
&delta_y);
if (delta_y < 0) {
direction_up = true;
} else if (delta_y > 0) {
direction_up = false;
}
}
if (direction_up) {
if (volume_ + 1 < 100) pa_cvolume_inc(&pa_volume, change);
} else {
if (volume_ - 1 > 0) pa_cvolume_dec(&pa_volume, change);
}
pa_context_set_sink_volume_by_index(context_, sink_idx_, &pa_volume,
volumeModifyCb, this);
return true;
}
/*
* Called when an event we subscribed to occurs.
*/
@ -75,21 +129,34 @@ void waybar::modules::Pulseaudio::subscribeCb(pa_context* context,
}
}
/*
* Called in response to a volume change request
*/
void waybar::modules::Pulseaudio::volumeModifyCb(pa_context *c, int success,
void *data) {
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
if (success) {
pa_context_get_sink_info_by_index(pa->context_, pa->sink_idx_, sinkInfoCb,
data);
}
}
/*
* Called when the requested sink information is ready.
*/
void waybar::modules::Pulseaudio::sinkInfoCb(pa_context* /*context*/,
const pa_sink_info* i, int /*eol*/, void* data)
{
void waybar::modules::Pulseaudio::sinkInfoCb(pa_context * /*context*/,
const pa_sink_info *i, int /*eol*/,
void *data) {
if (i != nullptr) {
auto pa = static_cast<waybar::modules::Pulseaudio *>(data);
float volume = static_cast<float>(pa_cvolume_avg(&(i->volume)))
/ float{PA_VOLUME_NORM};
pa->pa_volume_ = i->volume;
float volume = static_cast<float>(pa_cvolume_avg(&(pa->pa_volume_))) /
float{PA_VOLUME_NORM};
pa->sink_idx_ = i->index;
pa->volume_ = std::round(volume * 100.0f);
pa->muted_ = i->mute != 0;
pa->desc_ = i->description;
pa->port_name_ = i->active_port->name;
pa->port_name_ = i->active_port ? i->active_port->name : "Unknown";
pa->dp.emit();
}
}
@ -141,8 +208,11 @@ auto waybar::modules::Pulseaudio::update() -> void
label_.get_style_context()->remove_class("muted");
label_.get_style_context()->add_class("bluetooth");
}
label_.set_label(fmt::format(format,
fmt::arg("volume", volume_),
fmt::arg("icon", getIcon(volume_, getPortIcon()))));
label_.set_label(
fmt::format(format, fmt::arg("volume", volume_),
fmt::arg("icon", getIcon(volume_, getPortIcon()))));
label_.set_tooltip_text(desc_);
if (scrolling_) {
scrolling_ = false;
}
}

View File

@ -4,8 +4,8 @@
using namespace waybar::modules::SNI;
Host::Host(Glib::Dispatcher* dp)
: dp_(dp)
Host::Host(Glib::Dispatcher* dp, const Json::Value &config)
: dp_(dp), config_(config)
{
GBusNameOwnerFlags flags = static_cast<GBusNameOwnerFlags>(
G_BUS_NAME_OWNER_FLAGS_NONE);
@ -33,6 +33,7 @@ void Host::nameAppeared(GDBusConnection* connection,
auto host = static_cast<SNI::Host *>(data);
if (host->cancellable_ != nullptr) {
// TODO
return;
}
host->cancellable_ = g_cancellable_new();
sn_watcher_proxy_new(
@ -146,5 +147,5 @@ std::tuple<std::string, std::string> Host::getBusNameAndObjectPath(
void Host::addRegisteredItem(const gchar* service)
{
auto [bus_name, object_path] = getBusNameAndObjectPath(service);
items.emplace_back(bus_name, object_path, dp_);
items.emplace_back(bus_name, object_path, dp_, config_);
}

View File

@ -4,9 +4,14 @@
#include <libdbusmenu-gtk/dbusmenu-gtk.h>
waybar::modules::SNI::Item::Item(std::string bn, std::string op,
Glib::Dispatcher *dp)
Glib::Dispatcher *dp, Json::Value config)
: bus_name(bn), object_path(op), event_box(), icon_size(16),
effective_icon_size(0), image(Gtk::manage(new Gtk::Image())), dp_(dp) {
effective_icon_size(0), image(Gtk::manage(new Gtk::Image())),
dp_(dp), config_(config)
{
if (config_["icon-size"].isUInt()) {
icon_size = config_["icon-size"].asUInt();
}
event_box.add(*image);
event_box.add_events(Gdk::BUTTON_PRESS_MASK);
event_box.signal_button_press_event().connect(
@ -20,8 +25,7 @@ waybar::modules::SNI::Item::Item(std::string bn, std::string op,
void waybar::modules::SNI::Item::proxyReady(GObject *obj, GAsyncResult *res,
gpointer data) {
GError *error = nullptr;
SnItem *proxy =
sn_item_proxy_new_for_bus_finish(res, &error);
SnItem *proxy = sn_item_proxy_new_for_bus_finish(res, &error);
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
g_error_free(error);
return;
@ -113,6 +117,7 @@ void waybar::modules::SNI::Item::getAll(GObject *obj, GAsyncResult *res,
item->icon_theme_path.c_str());
}
item->updateImage();
item->updateMenu();
item->dp_->emit();
// TODO: handle change
}
@ -165,45 +170,56 @@ waybar::modules::SNI::Item::extractPixBuf(GVariant *variant) {
return Glib::RefPtr<Gdk::Pixbuf>{};
}
void waybar::modules::SNI::Item::updateMenu()
{
event_box.set_tooltip_text(title);
if (gtk_menu == nullptr && !menu.empty()) {
auto dbmenu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data());
if (dbmenu != nullptr) {
g_object_ref_sink(dbmenu);
gtk_menu = Glib::wrap(GTK_MENU(dbmenu), false);
gtk_menu->attach_to_widget(event_box);
}
}
}
void waybar::modules::SNI::Item::updateImage()
{
image->set_from_icon_name("image-missing", Gtk::ICON_SIZE_MENU);
image->set_pixel_size(icon_size);
if (!icon_name.empty()) {
auto pixbuf = getIconByName(icon_name, icon_size);
if (pixbuf->gobj() == nullptr) {
try {
// Try to find icons specified by path and filename
try {
pixbuf = Gdk::Pixbuf::create_from_file(icon_name);
#ifdef FILESYSTEM_EXPERIMENTAL
if (std::experimental::filesystem::exists(icon_name)) {
#else
if (std::filesystem::exists(icon_name)) {
#endif
auto pixbuf = Gdk::Pixbuf::create_from_file(icon_name);
if (pixbuf->gobj() != nullptr) {
// An icon specified by path and filename may be the wrong size for
// the tray
pixbuf->scale_simple(icon_size - 2, icon_size - 2,
Gdk::InterpType::INTERP_BILINEAR);
pixbuf = pixbuf->scale_simple(icon_size, icon_size,
Gdk::InterpType::INTERP_BILINEAR);
image->set(pixbuf);
}
} catch (Glib::Error &e) {
std::cerr << "Exception: " << e.what() << std::endl;
pixbuf = getIconByName("image-missing", icon_size);
} else {
image->set(getIconByName(icon_name, icon_size));
}
} catch (Glib::Error &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
if (pixbuf->gobj() == nullptr) {
pixbuf = getIconByName("image-missing", icon_size);
}
image->set(pixbuf);
} else if (icon_pixmap) {
// An icon extracted may be the wrong size for the tray
icon_pixmap = icon_pixmap->scale_simple(icon_size, icon_size,
Gdk::InterpType::INTERP_BILINEAR);
image->set(icon_pixmap);
} else {
image->set_from_icon_name("image-missing", Gtk::ICON_SIZE_MENU);
image->set_pixel_size(icon_size);
}
if (!menu.empty()) {
auto *dbmenu = dbusmenu_gtkmenu_new(bus_name.data(), menu.data());
if (dbmenu)
gtk_menu = Glib::wrap(GTK_MENU(dbmenu), false);
}
}
Glib::RefPtr<Gdk::Pixbuf>
waybar::modules::SNI::Item::getIconByName(std::string name, int request_size) {
int icon_size = 0;
int tmp_size = 0;
Glib::RefPtr<Gtk::IconTheme> icon_theme = Gtk::IconTheme::get_default();
icon_theme->rescan_if_needed();
auto sizes = icon_theme->get_icon_sizes(name.c_str());
@ -211,41 +227,43 @@ waybar::modules::SNI::Item::getIconByName(std::string name, int request_size) {
for (auto const &size : sizes) {
// -1 == scalable
if (size == request_size || size == -1) {
icon_size = request_size;
tmp_size = request_size;
break;
} else if (size < request_size || size > icon_size) {
icon_size = size;
} else if (size < request_size || size > tmp_size) {
tmp_size = size;
}
}
if (icon_size == 0) {
icon_size = request_size;
if (tmp_size == 0) {
tmp_size = request_size;
}
return icon_theme->load_icon(name.c_str(), icon_size,
return icon_theme->load_icon(name.c_str(), tmp_size,
Gtk::IconLookupFlags::ICON_LOOKUP_FORCE_SIZE);
}
void waybar::modules::SNI::Item::handleActivate(GObject *src, GAsyncResult *res,
gpointer data) {
auto item = static_cast<SNI::Item *>(data);
sn_item_call_activate_finish(item->proxy_, res,
nullptr);
sn_item_call_activate_finish(item->proxy_, res, nullptr);
}
void waybar::modules::SNI::Item::handleSecondaryActivate(GObject *src,
GAsyncResult *res,
gpointer data) {
auto item = static_cast<SNI::Item *>(data);
sn_item_call_secondary_activate_finish(item->proxy_,
res, nullptr);
sn_item_call_secondary_activate_finish(item->proxy_, res, nullptr);
}
bool waybar::modules::SNI::Item::handleClick(GdkEventButton *const &ev) {
if (ev->type == GDK_BUTTON_PRESS) {
if (gtk_menu) {
if (!gtk_menu->get_attach_widget()) {
gtk_menu->attach_to_widget(event_box);
}
if (gtk_menu && gtk_menu->get_children().size() > 0) {
#if GTK_CHECK_VERSION(3, 22, 0)
gtk_menu->popup_at_widget(reinterpret_cast<Gtk::Widget*>(&event_box),
Gdk::GRAVITY_NORTH_WEST, Gdk::GRAVITY_NORTH_WEST,
reinterpret_cast<GdkEvent*>(ev));
#else
gtk_menu->popup(ev->button, ev->time);
#endif
gtk_menu->set_state_flags(Gtk::STATE_FLAG_ACTIVE, false);
} else {
sn_item_call_activate(
proxy_, ev->x, ev->y, nullptr, &Item::handleActivate, this);

View File

@ -3,11 +3,18 @@
#include <iostream>
waybar::modules::SNI::Tray::Tray(const Json::Value &config)
: config_(config), watcher_(), host_(&dp) {}
: config_(config), watcher_(), host_(&dp, config)
{
std::cout << "Tray is in beta, so there may be bugs or even be unusable." << std::endl;
if (config_["spacing"].isUInt()) {
box_.set_spacing(config_["spacing"].asUInt());
}
}
auto waybar::modules::SNI::Tray::update() -> void {
auto childrens = box_.get_children();
childrens.erase(childrens.begin(), childrens.end());
for (auto &item : host_.items) {
item.event_box.set_tooltip_text(item.title);
box_.pack_start(item.event_box);
}
if (box_.get_children().size() > 0) {
@ -18,4 +25,6 @@ auto waybar::modules::SNI::Tray::update() -> void {
}
}
waybar::modules::SNI::Tray::operator Gtk::Widget &() { return box_; }
waybar::modules::SNI::Tray::operator Gtk::Widget &() {
return box_;
}

43
src/modules/sway/mode.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "modules/sway/mode.hpp"
waybar::modules::sway::Mode::Mode(Bar& bar, const Json::Value& config)
: ALabel(config, "{}"), bar_(bar)
{
ipc_.connect();
ipc_.subscribe("[ \"mode\" ]");
// Launch worker
worker();
}
void waybar::modules::sway::Mode::worker()
{
thread_ = [this] {
try {
auto res = ipc_.handleEvent();
auto parsed = parser_.parse(res.payload);
if ((parsed["change"]) != "default" ) {
mode_ = parsed["change"].asString();
dp.emit();
}
else if ((parsed["change"]) == "default" ) {
mode_.clear();
dp.emit();
}
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
};
}
auto waybar::modules::sway::Mode::update() -> void
{
if (mode_.empty()) {
label_.set_name("");
label_.hide();
} else {
label_.set_name("mode");
label_.set_text(fmt::format(format_, mode_));
label_.set_tooltip_text(mode_);
label_.show();
}
}

View File

@ -5,7 +5,7 @@ waybar::modules::sway::Window::Window(Bar &bar, const Json::Value& config)
{
label_.set_name("window");
ipc_.connect();
ipc_.subscribe("[ \"window\" ]");
ipc_.subscribe("[\"window\",\"workspace\"]");
getFocusedWindow();
// Launch worker
worker();
@ -22,9 +22,11 @@ void waybar::modules::sway::Window::worker()
window_ = parsed["container"]["name"].asString();
windowId_ = parsed["container"]["id"].asInt();
dp.emit();
} else if (parsed["change"] == "close"
} else if ((parsed["change"] == "close"
&& parsed["container"]["focused"].asBool()
&& windowId_ == parsed["container"]["id"].asInt()) {
&& windowId_ == parsed["container"]["id"].asInt())
|| (parsed["change"] == "focus" && parsed["current"]["focus"].isArray()
&& parsed["current"]["focus"].empty())) {
window_.clear();
windowId_ = -1;
dp.emit();

View File

@ -1,10 +1,10 @@
[wrap-file]
directory = fmt-4.1.0
directory = fmt-5.2.0
source_url = https://github.com/fmtlib/fmt/archive/4.1.0.tar.gz
source_filename = fmt-4.1.0.tar.gz
source_hash = 46628a2f068d0e33c716be0ed9dcae4370242df135aed663a180b9fd8e36733d
source_url = https://github.com/fmtlib/fmt/archive/5.2.0.tar.gz
source_filename = fmt-5.2.0.tar.gz
source_hash = b0e8c71a8fb906123966686f788e83cd95ae499afe9c25ff6284f624488435ac
patch_url = https://wrapdb.mesonbuild.com/v1/projects/fmt/4.1.0/1/get_zip
patch_filename = fmt-4.1.0-1-wrap.zip
patch_hash = 741931f01e558491724fc1c67bff996d1df79c0277626fc463de138052c9ecc0
patch_url = https://wrapdb.mesonbuild.com/v1/projects/fmt/5.2.0/1/get_zip
patch_filename = fmt-5.2.0-1-wrap.zip
patch_hash = 04005310ad939bc640ca0eb918e6b5390dbd5b5cb9d58636eb7c442306aa14cd