Merge tag '3.5.7'

This commit is contained in:
Przemek Grondek 2023-08-05 17:26:56 +02:00
commit 771cd1fd98
12 changed files with 229 additions and 111 deletions

View File

@ -1,4 +1,5 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
Each release should have the following subsections, if entries exist, in the Each release should have the following subsections, if entries exist, in the
given order: `Breaking`, `Build`, `Deprecated`, `Removed`, `Added`, `Changed`, 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)) ([`#2040`](https://github.com/polybar/polybar/issues/2040))
[Unreleased]: https://github.com/polybar/polybar/compare/3.5.2...HEAD [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

View File

@ -13,12 +13,22 @@
# documentation root, use os.path.abspath to make it absolute, like shown here. # documentation root, use os.path.abspath to make it absolute, like shown here.
# #
import os import os
from pathlib import Path
import datetime import datetime
import subprocess import sphinx
from docutils.nodes import Node import packaging.version
from typing import List
from sphinx.domains.changeset import VersionChange
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 ----------------------------------------------------- # -- Project information -----------------------------------------------------
@ -50,6 +60,11 @@ else:
# build folder. # build folder.
doc_path = '@doc_path@' 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 --------------------------------------------------- # -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here. # 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/polybar.5', 'polybar', 'configuration file for polybar(1)', [], 5)
] ]
man_make_section_directory = False
# -- Options for Texinfo output ---------------------------------------------- # -- Options for Texinfo output ----------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples # 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. # The 'versionadded' and 'versionchanged' directives are overridden.
suppress_warnings = ['app.add_directive'] suppress_warnings = ['app.add_directive']
def setup(app): # It is not exactly clear in which version the VersionChange class was
app.add_directive('deprecated', VersionDirective) # introduced, but we know it is available in at least 1.8.5.
app.add_directive('versionadded', VersionDirective) # This feature is mainly needed for the online docs on readthedocs for the docs
app.add_directive('versionchanged', VersionDirective) # 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): from typing import List
""" from docutils.nodes import Node
Overwrites the Sphinx directive for versionchanged, versionadded, and from sphinx.domains.changeset import VersionChange
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)
if completed.returncode != 0: def setup(app):
self.arguments[0] += " (unreleased)" 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()

View File

@ -4,12 +4,12 @@
#include "common.hpp" #include "common.hpp"
#include "utils/concurrency.hpp" #include "utils/concurrency.hpp"
#include "x11/xembed.hpp"
POLYBAR_NS POLYBAR_NS
// fwd declarations // fwd declarations
class connection; class connection;
struct xembed_data;
class tray_client { class tray_client {
public: public:
@ -28,7 +28,10 @@ class tray_client {
void mapped(bool state); void mapped(bool state);
xcb_window_t window() const; 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 ensure_state() const;
void reconfigure(int x, int y) const; void reconfigure(int x, int y) const;
@ -38,7 +41,18 @@ class tray_client {
connection& m_connection; connection& m_connection;
xcb_window_t m_window{0}; 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}; bool m_mapped{false};
unsigned int m_width; unsigned int m_width;

View File

@ -34,7 +34,6 @@ using namespace std::chrono_literals;
// fwd declarations // fwd declarations
class connection; class connection;
struct xembed_data;
class background_manager; class background_manager;
class bg_slice; class bg_slice;

View File

@ -21,24 +21,41 @@ POLYBAR_NS
#define XEMBED_FOCUS_FIRST 1 #define XEMBED_FOCUS_FIRST 1
#define XEMBED_FOCUS_LAST 1 #define XEMBED_FOCUS_LAST 1
struct xembed_data { /**
unsigned long version; * Max XEMBED version supported.
unsigned long flags; */
xcb_timestamp_t time; #define XEMBED_MAX_VERSION UINT32_C(0)
xcb_atom_t xembed;
xcb_atom_t xembed_info;
};
/**
* 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 { 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_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 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_activated(connection& conn, xcb_window_t win);
void notify_deactivated(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_focused(connection& conn, xcb_window_t win, long focus_type);
void notify_unfocused(connection& conn, xcb_window_t win); void notify_unfocused(connection& conn, xcb_window_t win);
void unembed(connection& conn, xcb_window_t win, xcb_window_t root); void unembed(connection& conn, xcb_window_t win, xcb_window_t root);
} } // namespace xembed
POLYBAR_NS_END POLYBAR_NS_END

View File

@ -225,6 +225,10 @@ chrono::duration<double> config::convert(string&& value) const {
template <> template <>
rgba config::convert(string&& value) const { rgba config::convert(string&& value) const {
if (value.empty()) {
return rgba{};
}
rgba ret{value}; rgba ret{value};
if (!ret.has_color()) { if (!ret.has_color()) {

View File

@ -655,16 +655,7 @@ bool controller::process_update(bool force) {
block_contents += padding_right; block_contents += padding_right;
} }
// Strip unnecessary reset tags contents += block_contents;
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, "}%{", " ");
} }
try { try {

View File

@ -38,18 +38,15 @@ namespace modules {
m_actions.emplace(make_pair<mousebtn, string>(mousebtn::DOUBLE_RIGHT, m_conf.get(name(), "double-click-right", ""s))); m_actions.emplace(make_pair<mousebtn, string>(mousebtn::DOUBLE_RIGHT, m_conf.get(name(), "double-click-right", ""s)));
// clang-format on // clang-format on
const auto pid_token = [](string& s) { const auto pid_token = [](const string& s) {
string::size_type p = s.find("%pid%"); return string_util::replace_all(s, "%pid%", to_string(getpid()));
if (p != string::npos) {
s.replace(p, 5, to_string(getpid()));
}
}; };
for (auto& action : m_actions) { for (auto& action : m_actions) {
pid_token(action.second); action.second = pid_token(action.second);
} }
for (auto& hook : m_hooks) { for (auto& hook : m_hooks) {
pid_token(hook->command); hook->command = pid_token(hook->command);
} }
m_formatter->add(DEFAULT_FORMAT, TAG_OUTPUT, {TAG_OUTPUT}); m_formatter->add(DEFAULT_FORMAT, TAG_OUTPUT, {TAG_OUTPUT});

View File

@ -1,19 +1,15 @@
#include "x11/tray_client.hpp"
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_aux.h> #include <xcb/xcb_aux.h>
#include "utils/memory.hpp" #include "utils/memory.hpp"
#include "x11/connection.hpp" #include "x11/connection.hpp"
#include "x11/tray_client.hpp"
#include "x11/xembed.hpp"
POLYBAR_NS POLYBAR_NS
tray_client::tray_client(connection& conn, xcb_window_t win, unsigned int w, unsigned int h) 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_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;
}
tray_client::~tray_client() { tray_client::~tray_client() {
xembed::unembed(m_connection, window(), m_connection.root()); xembed::unembed(m_connection, window(), m_connection.root());
@ -28,11 +24,7 @@ unsigned int tray_client::height() const {
} }
void tray_client::clear_window() const { void tray_client::clear_window() const {
try { m_connection.clear_area_checked(1, window(), 0, 0, width(), height());
m_connection.clear_area_checked(1, window(), 0, 0, width(), height());
} catch (const xpp::x::error::window& err) {
// ignore
}
} }
/** /**
@ -63,20 +55,31 @@ xcb_window_t tray_client::window() const {
return m_window; return m_window;
} }
/** void tray_client::query_xembed() {
* Get xembed data pointer m_xembed_supported = xembed::query(m_connection, m_window, m_xembed);
*/ }
xembed_data* tray_client::xembed() const {
return m_xembed.get(); 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 * Make sure that the window mapping state is correct
*/ */
void tray_client::ensure_state() const { 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()); 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()); m_connection.unmap_window_checked(window());
} }
} }

View File

@ -21,6 +21,12 @@
#include "x11/winspec.hpp" #include "x11/winspec.hpp"
#include "x11/xembed.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 // TODO: 32-bit visual
@ -427,13 +433,21 @@ void tray_manager::refresh_window() {
m_connection.poly_fill_rectangle(m_pixmap, m_gc, 1, &rect); m_connection.poly_fill_rectangle(m_pixmap, m_gc, 1, &rect);
} }
if (m_surface) if (m_surface) {
m_surface->flush(); m_surface->flush();
}
m_connection.clear_area(0, m_tray, 0, 0, width, height); m_connection.clear_area(0, m_tray, 0, 0, width, height);
for (auto&& client : m_clients) { 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(); m_connection.flush();
@ -477,8 +491,8 @@ void tray_manager::create_window() {
<< cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT) << cw_class(XCB_WINDOW_CLASS_INPUT_OUTPUT)
<< cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED) << cw_params_backing_store(XCB_BACKING_STORE_WHEN_MAPPED)
<< cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT << cw_params_event_mask(XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
|XCB_EVENT_MASK_STRUCTURE_NOTIFY |XCB_EVENT_MASK_STRUCTURE_NOTIFY
|XCB_EVENT_MASK_EXPOSURE) |XCB_EVENT_MASK_EXPOSURE)
<< cw_params_override_redirect(true); << cw_params_override_redirect(true);
// clang-format on // clang-format on
@ -726,26 +740,29 @@ void tray_manager::track_selection_owner(xcb_window_t owner) {
* Process client docking request * Process client docking request
*/ */
void tray_manager::process_docking_request(xcb_window_t win) { 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)); m_clients.emplace_back(factory_util::shared<tray_client>(m_connection, win, m_opts.width, m_opts.height));
auto& client = m_clients.back(); auto& client = m_clients.back();
try { try {
m_log.trace("tray: Get client _XEMBED_INFO"); client->query_xembed();
xembed::query(m_connection, win, client->xembed());
} catch (const application_error& err) {
m_log.err(err.what());
} catch (const xpp::x::error::window& err) { } catch (const xpp::x::error::window& err) {
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what()); m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
remove_client(win, true); remove_client(win, true);
return; 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 { try {
const unsigned int mask{XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK}; const unsigned int mask = XCB_CW_EVENT_MASK;
const unsigned int values[]{ const unsigned int values[]{XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
XCB_BACK_PIXMAP_PARENT_RELATIVE, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY};
m_log.trace("tray: Update client window"); m_log.trace("tray: Update client window");
m_connection.change_window_attributes_checked(client->window(), mask, values); 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( m_connection.reparent_window_checked(
client->window(), m_tray, calculate_client_x(client->window()), calculate_client_y()); client->window(), m_tray, calculate_client_x(client->window()), calculate_client_y());
m_log.trace("tray: Send embbeded notification to client"); if (client->is_xembed_supported()) {
xembed::notify_embedded(m_connection, client->window(), m_tray, client->xembed()->version); 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_log.trace("tray: Map client");
m_connection.map_window_checked(client->window()); 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); 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)); m_log.trace("tray: _XEMBED_INFO: %s", m_connection.id(evt->window));
auto xd = client->xembed();
auto win = client->window(); auto win = client->window();
if (evt->state == XCB_PROPERTY_NEW_VALUE) { if (evt->state == XCB_PROPERTY_NEW_VALUE) {
@ -1021,20 +1040,17 @@ void tray_manager::handle(const evt::property_notify& evt) {
} }
try { try {
m_log.trace("tray: Get client _XEMBED_INFO"); client->query_xembed();
xembed::query(m_connection, win, xd);
} catch (const application_error& err) {
m_log.err(err.what());
return;
} catch (const xpp::x::error::window& err) { } catch (const xpp::x::error::window& err) {
m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what()); m_log.err("Failed to query _XEMBED_INFO, removing client... (%s)", err.what());
remove_client(win, true); remove_client(win, true);
return; 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(); reconfigure();
} }
} }

View File

@ -5,26 +5,40 @@
POLYBAR_NS POLYBAR_NS
namespace xembed { 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 * 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) { bool query(connection& conn, xcb_window_t win, info& data) {
auto info = conn.get_property(false, win, _XEMBED_INFO, XCB_GET_PROPERTY_TYPE_ANY, 0L, 2); auto info = conn.get_property(false, win, _XEMBED_INFO, _XEMBED_INFO, 0L, 2);
if (info->value_len == 0) { 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; return true;
data->xembed_info = _XEMBED_INFO;
data->time = XCB_CURRENT_TIME;
data->flags = xembed_data[1];
data->version = xembed_data[0];
return data;
} }
/** /**
@ -53,8 +67,8 @@ namespace xembed {
/** /**
* Acknowledge window embedding * Acknowledge window embedding
*/ */
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) {
send_message(conn, win, XEMBED_EMBEDDED_NOTIFY, 0, embedder, version); send_message(conn, win, XEMBED_EMBEDDED_NOTIFY, 0, embedder, std::min(version, XEMBED_MAX_VERSION));
} }
/** /**

View File

@ -1,4 +1,4 @@
# Polybar version information # Polybar version information
# Update this on every release # Update this on every release
# This is used to create the version string if a git repo is not available # This is used to create the version string if a git repo is not available
3.5.2 3.5.7