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]
|
||||
type = internal/dwm
|
||||
format = <label-tags> <label-layout> <label-title>
|
||||
format = <label-tags> <label-layout> <label-floating> <label-title>
|
||||
|
||||
enable-tags-click = false
|
||||
enable-layout-click = false
|
||||
|
@ -56,7 +56,7 @@ namespace modules {
|
||||
auto input(string&& cmd) -> bool override;
|
||||
|
||||
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%"};
|
||||
|
||||
/**
|
||||
@ -75,6 +75,11 @@ namespace modules {
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -140,6 +145,14 @@ namespace modules {
|
||||
*/
|
||||
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
|
||||
* pointers to the active monitor and bar monitor.
|
||||
@ -159,6 +172,12 @@ namespace modules {
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -246,6 +265,11 @@ namespace modules {
|
||||
*/
|
||||
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
|
||||
* this symbol. The default is monocle mode [M].
|
||||
@ -288,6 +312,11 @@ namespace modules {
|
||||
*/
|
||||
label_t m_layout_label;
|
||||
|
||||
/**
|
||||
* Shown when currently focused window is floating
|
||||
*/
|
||||
label_t m_floating_label;
|
||||
|
||||
/**
|
||||
* Inserted between tags
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ namespace modules {
|
||||
m_ipc = factory_util::unique<dwmipc::Connection>(socket_path);
|
||||
|
||||
// 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
|
||||
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%");
|
||||
}
|
||||
|
||||
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)) {
|
||||
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));
|
||||
}
|
||||
|
||||
if (m_floating_label) {
|
||||
update_floating_label();
|
||||
}
|
||||
|
||||
if (m_layout_label) {
|
||||
auto 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);
|
||||
}
|
||||
|
||||
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
|
||||
m_ipc->on_monitor_focus_change = [this](const dwmipc::MonitorFocusChangeEvent& ev) {
|
||||
this->on_monitor_focus_change(ev);
|
||||
@ -154,6 +170,11 @@ namespace modules {
|
||||
auto dwm_module::build(builder* builder, const string& tag) const -> bool {
|
||||
if (tag == TAG_LABEL_TITLE) {
|
||||
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) {
|
||||
if (m_layout_click) {
|
||||
// Toggle between secondary and default layout
|
||||
@ -353,6 +374,21 @@ namespace modules {
|
||||
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 {
|
||||
try {
|
||||
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) {
|
||||
if (ev.monitor_num == m_bar_mon->num) {
|
||||
m_focused_client_id = ev.new_win_id;
|
||||
update_title_label();
|
||||
update_floating_label();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user