Merge tag '3.5.7'
This commit is contained in:
commit
771cd1fd98
36
CHANGELOG.md
36
CHANGELOG.md
@ -1,4 +1,5 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
Each release should have the following subsections, if entries exist, in the
|
||||
given order: `Breaking`, `Build`, `Deprecated`, `Removed`, `Added`, `Changed`,
|
||||
@ -56,3 +57,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
([`#2040`](https://github.com/polybar/polybar/issues/2040))
|
||||
|
||||
[Unreleased]: https://github.com/polybar/polybar/compare/3.5.2...HEAD
|
||||
## [3.5.7] - 2021-09-21
|
||||
### Fixed
|
||||
- The tray mistakenly removed tray icons that did not support XEMBED
|
||||
([`#2479`](https://github.com/polybar/polybar/issues/2479),
|
||||
[`#2442`](https://github.com/polybar/polybar/issues/2442))
|
||||
- `custom/ipc`: Only the first appearance of the `%pid%` token was replaced
|
||||
([`#2500`](https://github.com/polybar/polybar/issues/2500))
|
||||
|
||||
## [3.5.6] - 2021-05-24
|
||||
### Build
|
||||
- Support building documentation on sphinx 4.0 ([`#2424`](https://github.com/polybar/polybar/issues/2424))
|
||||
### Fixed
|
||||
- Tray icons sometimes appears outside of bar ([`#2430`](https://github.com/polybar/polybar/issues/2430), [`#1679`](https://github.com/polybar/polybar/issues/1679))
|
||||
- Crash in the i3 module ([`#2416`](https://github.com/polybar/polybar/issues/2416))
|
||||
|
||||
## [3.5.5] - 2021-03-01
|
||||
### Build
|
||||
- Support older python sphinx versions again ([`#2356`](https://github.com/polybar/polybar/issues/2356))
|
||||
|
||||
## [3.5.4] - 2021-01-07
|
||||
### Fixed
|
||||
- Wrong text displayed if module text ends with `}` ([`#2331`](https://github.com/polybar/polybar/issues/2331))
|
||||
|
||||
## [3.5.3] - 2020-12-23
|
||||
### Build
|
||||
- Don't use `git` when building documentation ([`#2309`](https://github.com/polybar/polybar/issues/2309))
|
||||
### Fixed
|
||||
- Empty color values are no longer treated as invalid and no longer produce an error.
|
||||
|
||||
[Unreleased]: https://github.com/polybar/polybar/compare/3.5.7...HEAD
|
||||
[3.5.7]: https://github.com/polybar/polybar/releases/tag/3.5.7
|
||||
[3.5.6]: https://github.com/polybar/polybar/releases/tag/3.5.6
|
||||
[3.5.5]: https://github.com/polybar/polybar/releases/tag/3.5.5
|
||||
[3.5.4]: https://github.com/polybar/polybar/releases/tag/3.5.4
|
||||
[3.5.3]: https://github.com/polybar/polybar/releases/tag/3.5.3
|
||||
|
69
doc/conf.py
69
doc/conf.py
@ -13,12 +13,22 @@
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
from pathlib import Path
|
||||
import datetime
|
||||
import subprocess
|
||||
from docutils.nodes import Node
|
||||
from typing import List
|
||||
from sphinx.domains.changeset import VersionChange
|
||||
import sphinx
|
||||
import packaging.version
|
||||
|
||||
def get_version(root_path):
|
||||
"""
|
||||
Reads the polybar version from the version.txt at the root of the repo.
|
||||
"""
|
||||
path = Path(root_path) / "version.txt"
|
||||
with open(path, "r") as f:
|
||||
for line in f.readlines():
|
||||
if not line.startswith("#"):
|
||||
return packaging.version.parse(line)
|
||||
|
||||
raise RuntimeError("No version found in {}".format(path))
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
@ -50,6 +60,11 @@ else:
|
||||
# build folder.
|
||||
doc_path = '@doc_path@'
|
||||
|
||||
# The version from the version.txt file. Since we are not always first
|
||||
# configured by cmake, we don't necessarily have access to the current version
|
||||
# number
|
||||
version_txt = get_version(Path(doc_path).absolute().parent)
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
@ -170,6 +185,9 @@ man_pages = [
|
||||
('man/polybar.5', 'polybar', 'configuration file for polybar(1)', [], 5)
|
||||
]
|
||||
|
||||
man_make_section_directory = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
@ -202,23 +220,32 @@ epub_exclude_files = ['search.html']
|
||||
# The 'versionadded' and 'versionchanged' directives are overridden.
|
||||
suppress_warnings = ['app.add_directive']
|
||||
|
||||
def setup(app):
|
||||
app.add_directive('deprecated', VersionDirective)
|
||||
app.add_directive('versionadded', VersionDirective)
|
||||
app.add_directive('versionchanged', VersionDirective)
|
||||
# It is not exactly clear in which version the VersionChange class was
|
||||
# introduced, but we know it is available in at least 1.8.5.
|
||||
# This feature is mainly needed for the online docs on readthedocs for the docs
|
||||
# built from master, documentation built for proper releases should not even
|
||||
# mention unreleased changes. Because of that it's not that important that this
|
||||
# is added to local builds.
|
||||
if packaging.version.parse(sphinx.__version__) >= packaging.version.parse("1.8.5"):
|
||||
|
||||
class VersionDirective(VersionChange):
|
||||
"""
|
||||
Overwrites the Sphinx directive for versionchanged, versionadded, and
|
||||
deprecated and adds an unreleased tag to versions that are not yet released
|
||||
"""
|
||||
def run(self) -> List[Node]:
|
||||
# If the tag exists 'git rev-parse' will succeed and otherwise fail
|
||||
completed = subprocess.run(["git", "rev-parse", self.arguments[0]],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=doc_path,
|
||||
check=False)
|
||||
from typing import List
|
||||
from docutils.nodes import Node
|
||||
from sphinx.domains.changeset import VersionChange
|
||||
|
||||
if completed.returncode != 0:
|
||||
self.arguments[0] += " (unreleased)"
|
||||
def setup(app):
|
||||
app.add_directive('deprecated', VersionDirective)
|
||||
app.add_directive('versionadded', VersionDirective)
|
||||
app.add_directive('versionchanged', VersionDirective)
|
||||
|
||||
return super().run()
|
||||
class VersionDirective(VersionChange):
|
||||
"""
|
||||
Overwrites the Sphinx directive for versionchanged, versionadded, and
|
||||
deprecated and adds an unreleased tag to versions that are not yet released
|
||||
"""
|
||||
def run(self) -> List[Node]:
|
||||
directive_version = packaging.version.parse(self.arguments[0])
|
||||
|
||||
if directive_version > version_txt:
|
||||
self.arguments[0] += " (unreleased)"
|
||||
|
||||
return super().run()
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "utils/concurrency.hpp"
|
||||
#include "x11/xembed.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
// fwd declarations
|
||||
class connection;
|
||||
struct xembed_data;
|
||||
|
||||
class tray_client {
|
||||
public:
|
||||
@ -28,7 +28,10 @@ class tray_client {
|
||||
void mapped(bool state);
|
||||
|
||||
xcb_window_t window() const;
|
||||
xembed_data* xembed() const;
|
||||
|
||||
void query_xembed();
|
||||
bool is_xembed_supported() const;
|
||||
const xembed::info& get_xembed() const;
|
||||
|
||||
void ensure_state() const;
|
||||
void reconfigure(int x, int y) const;
|
||||
@ -38,7 +41,18 @@ class tray_client {
|
||||
connection& m_connection;
|
||||
xcb_window_t m_window{0};
|
||||
|
||||
shared_ptr<xembed_data> m_xembed;
|
||||
/**
|
||||
* Whether the client window supports XEMBED.
|
||||
*
|
||||
* A tray client can still work when it doesn't support XEMBED.
|
||||
*/
|
||||
bool m_xembed_supported{false};
|
||||
|
||||
/**
|
||||
* _XEMBED_INFO of the client window
|
||||
*/
|
||||
xembed::info m_xembed;
|
||||
|
||||
bool m_mapped{false};
|
||||
|
||||
unsigned int m_width;
|
||||
|
@ -34,7 +34,6 @@ using namespace std::chrono_literals;
|
||||
|
||||
// fwd declarations
|
||||
class connection;
|
||||
struct xembed_data;
|
||||
class background_manager;
|
||||
class bg_slice;
|
||||
|
||||
|
@ -21,24 +21,41 @@ POLYBAR_NS
|
||||
#define XEMBED_FOCUS_FIRST 1
|
||||
#define XEMBED_FOCUS_LAST 1
|
||||
|
||||
struct xembed_data {
|
||||
unsigned long version;
|
||||
unsigned long flags;
|
||||
xcb_timestamp_t time;
|
||||
xcb_atom_t xembed;
|
||||
xcb_atom_t xembed_info;
|
||||
};
|
||||
/**
|
||||
* Max XEMBED version supported.
|
||||
*/
|
||||
#define XEMBED_MAX_VERSION UINT32_C(0)
|
||||
|
||||
/**
|
||||
* Implementation of parts of the XEMBED spec (as much as needed to get the tray working).
|
||||
*
|
||||
* Ref: https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
|
||||
*/
|
||||
namespace xembed {
|
||||
xembed_data* query(connection& conn, xcb_window_t win, xembed_data* data);
|
||||
|
||||
class info {
|
||||
public:
|
||||
void set(uint32_t* data);
|
||||
|
||||
uint32_t get_version() const;
|
||||
uint32_t get_flags() const;
|
||||
|
||||
bool is_mapped() const;
|
||||
|
||||
protected:
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
bool query(connection& conn, xcb_window_t win, info& data);
|
||||
void send_message(connection& conn, xcb_window_t target, long message, long d1, long d2, long d3);
|
||||
void send_focus_event(connection& conn, xcb_window_t target);
|
||||
void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, long version);
|
||||
void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, uint32_t version);
|
||||
void notify_activated(connection& conn, xcb_window_t win);
|
||||
void notify_deactivated(connection& conn, xcb_window_t win);
|
||||
void notify_focused(connection& conn, xcb_window_t win, long focus_type);
|
||||
void notify_unfocused(connection& conn, xcb_window_t win);
|
||||
void unembed(connection& conn, xcb_window_t win, xcb_window_t root);
|
||||
}
|
||||
} // namespace xembed
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -225,6 +225,10 @@ chrono::duration<double> config::convert(string&& value) const {
|
||||
|
||||
template <>
|
||||
rgba config::convert(string&& value) const {
|
||||
if (value.empty()) {
|
||||
return rgba{};
|
||||
}
|
||||
|
||||
rgba ret{value};
|
||||
|
||||
if (!ret.has_color()) {
|
||||
|
@ -655,16 +655,7 @@ bool controller::process_update(bool force) {
|
||||
block_contents += padding_right;
|
||||
}
|
||||
|
||||
// Strip unnecessary reset tags
|
||||
block_contents = string_util::replace_all(block_contents, "T-}%{T", "T");
|
||||
block_contents = string_util::replace_all(block_contents, "B-}%{B#", "B#");
|
||||
block_contents = string_util::replace_all(block_contents, "F-}%{F#", "F#");
|
||||
block_contents = string_util::replace_all(block_contents, "U-}%{U#", "U#");
|
||||
block_contents = string_util::replace_all(block_contents, "u-}%{u#", "u#");
|
||||
block_contents = string_util::replace_all(block_contents, "o-}%{o#", "o#");
|
||||
|
||||
// Join consecutive tags
|
||||
contents += string_util::replace_all(block_contents, "}%{", " ");
|
||||
contents += block_contents;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -38,18 +38,15 @@ namespace modules {
|
||||
m_actions.emplace(make_pair<mousebtn, string>(mousebtn::DOUBLE_RIGHT, m_conf.get(name(), "double-click-right", ""s)));
|
||||
// clang-format on
|
||||
|
||||
const auto pid_token = [](string& s) {
|
||||
string::size_type p = s.find("%pid%");
|
||||
if (p != string::npos) {
|
||||
s.replace(p, 5, to_string(getpid()));
|
||||
}
|
||||
const auto pid_token = [](const string& s) {
|
||||
return string_util::replace_all(s, "%pid%", to_string(getpid()));
|
||||
};
|
||||
|
||||
for (auto& action : m_actions) {
|
||||
pid_token(action.second);
|
||||
action.second = pid_token(action.second);
|
||||
}
|
||||
for (auto& hook : m_hooks) {
|
||||
pid_token(hook->command);
|
||||
hook->command = pid_token(hook->command);
|
||||
}
|
||||
|
||||
m_formatter->add(DEFAULT_FORMAT, TAG_OUTPUT, {TAG_OUTPUT});
|
||||
|
@ -1,19 +1,15 @@
|
||||
#include "x11/tray_client.hpp"
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
|
||||
#include "utils/memory.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/tray_client.hpp"
|
||||
#include "x11/xembed.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
tray_client::tray_client(connection& conn, xcb_window_t win, unsigned int w, unsigned int h)
|
||||
: m_connection(conn), m_window(win), m_width(w), m_height(h) {
|
||||
m_xembed = memory_util::make_malloc_ptr<xembed_data>();
|
||||
m_xembed->version = XEMBED_VERSION;
|
||||
m_xembed->flags = XEMBED_MAPPED;
|
||||
}
|
||||
: m_connection(conn), m_window(win), m_width(w), m_height(h) {}
|
||||
|
||||
tray_client::~tray_client() {
|
||||
xembed::unembed(m_connection, window(), m_connection.root());
|
||||
@ -28,11 +24,7 @@ unsigned int tray_client::height() const {
|
||||
}
|
||||
|
||||
void tray_client::clear_window() const {
|
||||
try {
|
||||
m_connection.clear_area_checked(1, window(), 0, 0, width(), height());
|
||||
} catch (const xpp::x::error::window& err) {
|
||||
// ignore
|
||||
}
|
||||
m_connection.clear_area_checked(1, window(), 0, 0, width(), height());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,20 +55,31 @@ xcb_window_t tray_client::window() const {
|
||||
return m_window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get xembed data pointer
|
||||
*/
|
||||
xembed_data* tray_client::xembed() const {
|
||||
return m_xembed.get();
|
||||
void tray_client::query_xembed() {
|
||||
m_xembed_supported = xembed::query(m_connection, m_window, m_xembed);
|
||||
}
|
||||
|
||||
bool tray_client::is_xembed_supported() const {
|
||||
return m_xembed_supported;
|
||||
}
|
||||
|
||||
const xembed::info& tray_client::get_xembed() const {
|
||||
return m_xembed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the window mapping state is correct
|
||||
*/
|
||||
void tray_client::ensure_state() const {
|
||||
if (!mapped() && ((xembed()->flags & XEMBED_MAPPED) == XEMBED_MAPPED)) {
|
||||
bool should_be_mapped = true;
|
||||
|
||||
if (is_xembed_supported()) {
|
||||
should_be_mapped = m_xembed.is_mapped();
|
||||
}
|
||||
|
||||
if (!mapped() && should_be_mapped) {
|
||||
m_connection.map_window_checked(window());
|
||||
} else if (mapped() && ((xembed()->flags & XEMBED_MAPPED) != XEMBED_MAPPED)) {
|
||||
} else if (mapped() && !should_be_mapped) {
|
||||
m_connection.unmap_window_checked(window());
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,12 @@
|
||||
#include "x11/winspec.hpp"
|
||||
#include "x11/xembed.hpp"
|
||||
|
||||
/*
|
||||
* Tray implementation according to the System Tray Protocol.
|
||||
*
|
||||
* Ref: https://specifications.freedesktop.org/systemtray-spec/systemtray-spec-latest.html
|
||||
*/
|
||||
|
||||
// ====================================================================================================
|
||||
//
|
||||
// TODO: 32-bit visual
|
||||
@ -427,13 +433,21 @@ void tray_manager::refresh_window() {
|
||||
m_connection.poly_fill_rectangle(m_pixmap, m_gc, 1, &rect);
|
||||
}
|
||||
|
||||
if (m_surface)
|
||||
if (m_surface) {
|
||||
m_surface->flush();
|
||||
}
|
||||
|
||||
m_connection.clear_area(0, m_tray, 0, 0, width, height);
|
||||
|
||||
for (auto&& client : m_clients) {
|
||||
client->clear_window();
|
||||
try {
|
||||
if (client->mapped()) {
|
||||
client->clear_window();
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
m_log.err("Failed to clear tray client %s '%s' (%s)", m_connection.id(client->window()),
|
||||
ewmh_util::get_wm_name(client->window()), e.what());
|
||||
}
|
||||
}
|
||||
|
||||
m_connection.flush();
|
||||
@ -477,8 +491,8 @@ void tray_manager::create_window() {
|
||||
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
|
||||
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
|
||||
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|
||||
|XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||
|XCB_EVENT_MASK_EXPOSURE)
|
||||
|XCB_EVENT_MASK_STRUCTURE_NOTIFY
|
||||
|XCB_EVENT_MASK_EXPOSURE)
|
||||
<< cw_params_override_redirect(true);
|
||||
// clang-format on
|
||||
|
||||
@ -726,26 +740,29 @@ void tray_manager::track_selection_owner(xcb_window_t owner) {
|
||||
* Process client docking request
|
||||
*/
|
||||
void tray_manager::process_docking_request(xcb_window_t win) {
|
||||
m_log.info("Processing docking request from %s", m_connection.id(win));
|
||||
m_log.info("Processing docking request from '%s' (%s)", ewmh_util::get_wm_name(win), m_connection.id(win));
|
||||
|
||||
m_clients.emplace_back(factory_util::shared<tray_client>(m_connection, win, m_opts.width, m_opts.height));
|
||||
auto& client = m_clients.back();
|
||||
|
||||
try {
|
||||
m_log.trace("tray: Get client _XEMBED_INFO");
|
||||
xembed::query(m_connection, win, client->xembed());
|
||||
} catch (const application_error& err) {
|
||||
m_log.err(err.what());
|
||||
client->query_xembed();
|
||||
} catch (const xpp::x::error::window& err) {
|
||||
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
|
||||
remove_client(win, true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.trace("tray: xembed = %s", client->is_xembed_supported() ? "true" : "false");
|
||||
if (client->is_xembed_supported()) {
|
||||
m_log.trace("tray: version = 0x%x, flags = 0x%x, XEMBED_MAPPED = %s", client->get_xembed().get_version(),
|
||||
client->get_xembed().get_flags(), client->get_xembed().is_mapped() ? "true" : "false");
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const unsigned int mask{XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK};
|
||||
const unsigned int values[]{
|
||||
XCB_BACK_PIXMAP_PARENT_RELATIVE, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
||||
const unsigned int mask = XCB_CW_EVENT_MASK;
|
||||
const unsigned int values[]{XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
|
||||
|
||||
m_log.trace("tray: Update client window");
|
||||
m_connection.change_window_attributes_checked(client->window(), mask, values);
|
||||
@ -760,15 +777,18 @@ void tray_manager::process_docking_request(xcb_window_t win) {
|
||||
m_connection.reparent_window_checked(
|
||||
client->window(), m_tray, calculate_client_x(client->window()), calculate_client_y());
|
||||
|
||||
m_log.trace("tray: Send embbeded notification to client");
|
||||
xembed::notify_embedded(m_connection, client->window(), m_tray, client->xembed()->version);
|
||||
if (client->is_xembed_supported()) {
|
||||
m_log.trace("tray: Send embbeded notification to client");
|
||||
xembed::notify_embedded(m_connection, client->window(), m_tray, client->get_xembed().get_version());
|
||||
}
|
||||
|
||||
if (client->xembed()->flags & XEMBED_MAPPED) {
|
||||
if (!client->is_xembed_supported() || client->get_xembed().is_mapped()) {
|
||||
m_log.trace("tray: Map client");
|
||||
m_connection.map_window_checked(client->window());
|
||||
}
|
||||
} catch (const xpp::x::error::window& err) {
|
||||
m_log.err("Failed to setup tray client, removing... (%s)", err.what());
|
||||
|
||||
} catch (const std::exception& err) {
|
||||
m_log.err("Failed to setup tray client removing... (%s)", err.what());
|
||||
remove_client(win, false);
|
||||
}
|
||||
}
|
||||
@ -1013,7 +1033,6 @@ void tray_manager::handle(const evt::property_notify& evt) {
|
||||
|
||||
m_log.trace("tray: _XEMBED_INFO: %s", m_connection.id(evt->window));
|
||||
|
||||
auto xd = client->xembed();
|
||||
auto win = client->window();
|
||||
|
||||
if (evt->state == XCB_PROPERTY_NEW_VALUE) {
|
||||
@ -1021,20 +1040,17 @@ void tray_manager::handle(const evt::property_notify& evt) {
|
||||
}
|
||||
|
||||
try {
|
||||
m_log.trace("tray: Get client _XEMBED_INFO");
|
||||
xembed::query(m_connection, win, xd);
|
||||
} catch (const application_error& err) {
|
||||
m_log.err(err.what());
|
||||
return;
|
||||
client->query_xembed();
|
||||
} catch (const xpp::x::error::window& err) {
|
||||
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
|
||||
remove_client(win, true);
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.trace("tray: _XEMBED_INFO[0]=%u _XEMBED_INFO[1]=%u", xd->version, xd->flags);
|
||||
m_log.trace("tray: version = 0x%x, flags = 0x%x, XEMBED_MAPPED = %s", client->get_xembed().get_version(),
|
||||
client->get_xembed().get_flags(), client->get_xembed().is_mapped() ? "true" : "false");
|
||||
|
||||
if ((client->xembed()->flags & XEMBED_MAPPED) & XEMBED_MAPPED) {
|
||||
if (client->get_xembed().is_mapped()) {
|
||||
reconfigure();
|
||||
}
|
||||
}
|
||||
|
@ -5,26 +5,40 @@
|
||||
POLYBAR_NS
|
||||
|
||||
namespace xembed {
|
||||
|
||||
void info::set(uint32_t* data) {
|
||||
version = data[0];
|
||||
flags = data[1];
|
||||
}
|
||||
|
||||
uint32_t info::get_version() const {
|
||||
return version;
|
||||
}
|
||||
|
||||
uint32_t info::get_flags() const {
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool info::is_mapped() const {
|
||||
return (flags & XEMBED_MAPPED) == XEMBED_MAPPED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query _XEMBED_INFO for the given window
|
||||
*
|
||||
* \return Whether valid XEMBED info was found
|
||||
*/
|
||||
xembed_data* query(connection& conn, xcb_window_t win, xembed_data* data) {
|
||||
auto info = conn.get_property(false, win, _XEMBED_INFO, XCB_GET_PROPERTY_TYPE_ANY, 0L, 2);
|
||||
bool query(connection& conn, xcb_window_t win, info& data) {
|
||||
auto info = conn.get_property(false, win, _XEMBED_INFO, _XEMBED_INFO, 0L, 2);
|
||||
|
||||
if (info->value_len == 0) {
|
||||
throw application_error("Invalid _XEMBED_INFO for window " + conn.id(win));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> xembed_data{info.value<unsigned int>().begin(), info.value<unsigned int>().end()};
|
||||
std::vector<uint32_t> xembed_data{info.value<uint32_t>().begin(), info.value<uint32_t>().end()};
|
||||
data.set(xembed_data.data());
|
||||
|
||||
data->xembed = _XEMBED;
|
||||
data->xembed_info = _XEMBED_INFO;
|
||||
|
||||
data->time = XCB_CURRENT_TIME;
|
||||
data->flags = xembed_data[1];
|
||||
data->version = xembed_data[0];
|
||||
|
||||
return data;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,8 +67,8 @@ namespace xembed {
|
||||
/**
|
||||
* Acknowledge window embedding
|
||||
*/
|
||||
void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, long version) {
|
||||
send_message(conn, win, XEMBED_EMBEDDED_NOTIFY, 0, embedder, version);
|
||||
void notify_embedded(connection& conn, xcb_window_t win, xcb_window_t embedder, uint32_t version) {
|
||||
send_message(conn, win, XEMBED_EMBEDDED_NOTIFY, 0, embedder, std::min(version, XEMBED_MAX_VERSION));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Polybar version information
|
||||
# Update this on every release
|
||||
# This is used to create the version string if a git repo is not available
|
||||
3.5.2
|
||||
3.5.7
|
||||
|
Loading…
Reference in New Issue
Block a user