dwm: Add label-floating
This label is visible when the currently focused client is in floating mode and detached from the layout. It uses the focused_state_change_event as well as the focused_client_change_event to check if the focused client is floating and updates m_is_floating accordingly which will enable/disbale the floating label in the final output. update_floating_label is called when the floating state of the client is not known. The function queries dwm for the properties of the focused client and sets m_is_floating accordingly. This fixes issue #2.
This commit is contained in:
parent
3fa404e9ff
commit
02bd2e060d
@ -168,7 +168,7 @@ label-urgent-padding = 2
|
|||||||
|
|
||||||
[module/dwm]
|
[module/dwm]
|
||||||
type = internal/dwm
|
type = internal/dwm
|
||||||
format = <label-tags> <label-layout> <label-title>
|
format = <label-tags> <label-layout> <label-floating> <label-title>
|
||||||
|
|
||||||
enable-tags-click = false
|
enable-tags-click = false
|
||||||
enable-layout-click = false
|
enable-layout-click = false
|
||||||
|
@ -56,7 +56,7 @@ namespace modules {
|
|||||||
auto input(string&& cmd) -> bool override;
|
auto input(string&& cmd) -> bool override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr const char* DEFAULT_FORMAT_TAGS{"<label-tags> <label-layout> <label-title>"};
|
static constexpr const char* DEFAULT_FORMAT_TAGS{"<label-tags> <label-layout> <label-floating> <label-title>"};
|
||||||
static constexpr const char* DEFAULT_STATE_LABEL{"%name%"};
|
static constexpr const char* DEFAULT_STATE_LABEL{"%name%"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,6 +75,11 @@ namespace modules {
|
|||||||
*/
|
*/
|
||||||
static constexpr const char* TAG_LABEL_LAYOUT{"<label-layout>"};
|
static constexpr const char* TAG_LABEL_LAYOUT{"<label-layout>"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The floating label is shown when the selected window is floating
|
||||||
|
*/
|
||||||
|
static constexpr const char* TAG_LABEL_FLOATING{"<label-floating>"};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The title layout is replaced by the currently focused window title
|
* The title layout is replaced by the currently focused window title
|
||||||
*/
|
*/
|
||||||
@ -140,6 +145,14 @@ namespace modules {
|
|||||||
*/
|
*/
|
||||||
void on_focused_title_change(const dwmipc::FocusedTitleChangeEvent& ev);
|
void on_focused_title_change(const dwmipc::FocusedTitleChangeEvent& ev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by has_event when the state of the currently focused window
|
||||||
|
* changes. This updates the floating label.
|
||||||
|
*
|
||||||
|
* @param ev Event data
|
||||||
|
*/
|
||||||
|
void on_focused_state_change(const dwmipc::FocusedStateChangeEvent& ev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of monitors from dwm, store them in m_monitors, and update the
|
* Get a list of monitors from dwm, store them in m_monitors, and update the
|
||||||
* pointers to the active monitor and bar monitor.
|
* pointers to the active monitor and bar monitor.
|
||||||
@ -159,6 +172,12 @@ namespace modules {
|
|||||||
*/
|
*/
|
||||||
void update_title_label();
|
void update_title_label();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query dwm to determine if the currently focused client and update
|
||||||
|
* m_is_floating
|
||||||
|
*/
|
||||||
|
void update_floating_label();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate the tag's tag states to a state_t enum value
|
* Translate the tag's tag states to a state_t enum value
|
||||||
*
|
*
|
||||||
@ -246,6 +265,11 @@ namespace modules {
|
|||||||
*/
|
*/
|
||||||
bool m_layout_reverse{false};
|
bool m_layout_reverse{false};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, show floating label
|
||||||
|
*/
|
||||||
|
bool m_is_floating{false};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the layout symbol is clicked on, it will set the layout represented by
|
* If the layout symbol is clicked on, it will set the layout represented by
|
||||||
* this symbol. The default is monocle mode [M].
|
* this symbol. The default is monocle mode [M].
|
||||||
@ -288,6 +312,11 @@ namespace modules {
|
|||||||
*/
|
*/
|
||||||
label_t m_layout_label;
|
label_t m_layout_label;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shown when currently focused window is floating
|
||||||
|
*/
|
||||||
|
label_t m_floating_label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserted between tags
|
* Inserted between tags
|
||||||
*/
|
*/
|
||||||
|
@ -28,7 +28,7 @@ namespace modules {
|
|||||||
m_ipc = factory_util::unique<dwmipc::Connection>(socket_path);
|
m_ipc = factory_util::unique<dwmipc::Connection>(socket_path);
|
||||||
|
|
||||||
// Load configuration
|
// Load configuration
|
||||||
m_formatter->add(DEFAULT_FORMAT, DEFAULT_FORMAT_TAGS, {TAG_LABEL_TAGS, TAG_LABEL_LAYOUT, TAG_LABEL_TITLE});
|
m_formatter->add(DEFAULT_FORMAT, DEFAULT_FORMAT_TAGS, {TAG_LABEL_TAGS, TAG_LABEL_LAYOUT, TAG_LABEL_FLOATING, TAG_LABEL_TITLE});
|
||||||
|
|
||||||
// Populate m_state_labels map with labels and their states
|
// Populate m_state_labels map with labels and their states
|
||||||
if (m_formatter->has(TAG_LABEL_TAGS)) {
|
if (m_formatter->has(TAG_LABEL_TAGS)) {
|
||||||
@ -50,6 +50,10 @@ namespace modules {
|
|||||||
m_layout_label = load_optional_label(m_conf, name(), "label-layout", "%layout%");
|
m_layout_label = load_optional_label(m_conf, name(), "label-layout", "%layout%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_formatter->has(TAG_LABEL_FLOATING)) {
|
||||||
|
m_floating_label = load_optional_label(m_conf, name(), "label-floating", "");
|
||||||
|
}
|
||||||
|
|
||||||
if (m_formatter->has(TAG_LABEL_TITLE)) {
|
if (m_formatter->has(TAG_LABEL_TITLE)) {
|
||||||
m_title_label = load_optional_label(m_conf, name(), "label-title", "%title%");
|
m_title_label = load_optional_label(m_conf, name(), "label-title", "%title%");
|
||||||
}
|
}
|
||||||
@ -74,6 +78,10 @@ namespace modules {
|
|||||||
m_tags.emplace_back(t.tag_name, t.bit_mask, state, move(label));
|
m_tags.emplace_back(t.tag_name, t.bit_mask, state, move(label));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_floating_label) {
|
||||||
|
update_floating_label();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_layout_label) {
|
if (m_layout_label) {
|
||||||
auto layouts = m_ipc->get_layouts();
|
auto layouts = m_ipc->get_layouts();
|
||||||
m_layouts = m_ipc->get_layouts();
|
m_layouts = m_ipc->get_layouts();
|
||||||
@ -106,6 +114,14 @@ namespace modules {
|
|||||||
m_ipc->subscribe(dwmipc::Event::FOCUSED_TITLE_CHANGE);
|
m_ipc->subscribe(dwmipc::Event::FOCUSED_TITLE_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_floating_label) {
|
||||||
|
update_floating_label();
|
||||||
|
m_ipc->on_focused_state_change = [this](const dwmipc::FocusedStateChangeEvent& ev) {
|
||||||
|
this->on_focused_state_change(ev);
|
||||||
|
};
|
||||||
|
m_ipc->subscribe(dwmipc::Event::FOCUSED_STATE_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
// This event is for keeping track of the currently focused monitor
|
// This event is for keeping track of the currently focused monitor
|
||||||
m_ipc->on_monitor_focus_change = [this](const dwmipc::MonitorFocusChangeEvent& ev) {
|
m_ipc->on_monitor_focus_change = [this](const dwmipc::MonitorFocusChangeEvent& ev) {
|
||||||
this->on_monitor_focus_change(ev);
|
this->on_monitor_focus_change(ev);
|
||||||
@ -154,6 +170,11 @@ namespace modules {
|
|||||||
auto dwm_module::build(builder* builder, const string& tag) const -> bool {
|
auto dwm_module::build(builder* builder, const string& tag) const -> bool {
|
||||||
if (tag == TAG_LABEL_TITLE) {
|
if (tag == TAG_LABEL_TITLE) {
|
||||||
builder->node(m_title_label);
|
builder->node(m_title_label);
|
||||||
|
} else if (tag == TAG_LABEL_FLOATING) {
|
||||||
|
if (!m_is_floating) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
builder->node(m_floating_label);
|
||||||
} else if (tag == TAG_LABEL_LAYOUT) {
|
} else if (tag == TAG_LABEL_LAYOUT) {
|
||||||
if (m_layout_click) {
|
if (m_layout_click) {
|
||||||
// Toggle between secondary and default layout
|
// Toggle between secondary and default layout
|
||||||
@ -353,6 +374,21 @@ namespace modules {
|
|||||||
m_title_label->replace_token("%title%", new_title);
|
m_title_label->replace_token("%title%", new_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dwm_module::update_floating_label() {
|
||||||
|
if (m_focused_client_id != 0) {
|
||||||
|
try {
|
||||||
|
m_is_floating = m_ipc->get_client(m_focused_client_id)->states.is_floating;
|
||||||
|
} catch (const dwmipc::SocketClosedError& err) {
|
||||||
|
m_log.err("%s: Disconnected from socket: %s", name(), err.what());
|
||||||
|
reconnect_dwm();
|
||||||
|
} catch (const dwmipc::IPCError& err) {
|
||||||
|
throw module_error(err.what());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_is_floating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto dwm_module::reconnect_dwm() -> bool {
|
auto dwm_module::reconnect_dwm() -> bool {
|
||||||
try {
|
try {
|
||||||
if (!m_ipc->is_main_socket_connected()) {
|
if (!m_ipc->is_main_socket_connected()) {
|
||||||
@ -401,10 +437,17 @@ namespace modules {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dwm_module::on_focused_state_change(const dwmipc::FocusedStateChangeEvent& ev) {
|
||||||
|
if (ev.monitor_num == m_bar_mon->num && ev.client_window_id == m_focused_client_id) {
|
||||||
|
m_is_floating = ev.new_state.is_floating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void dwm_module::on_client_focus_change(const dwmipc::ClientFocusChangeEvent& ev) {
|
void dwm_module::on_client_focus_change(const dwmipc::ClientFocusChangeEvent& ev) {
|
||||||
if (ev.monitor_num == m_bar_mon->num) {
|
if (ev.monitor_num == m_bar_mon->num) {
|
||||||
m_focused_client_id = ev.new_win_id;
|
m_focused_client_id = ev.new_win_id;
|
||||||
update_title_label();
|
update_title_label();
|
||||||
|
update_floating_label();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user