refactor(x11): Cleanup
This commit is contained in:
parent
a5d6670121
commit
6692b4a8da
@ -13,15 +13,14 @@ addons:
|
||||
- llvm-toolchain-precise-3.8
|
||||
- sourceline: "ppa:george-edison55/george-edison"
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
- clang-3.8
|
||||
- cmake
|
||||
- cmake-data
|
||||
- g++-5
|
||||
- gcc-5
|
||||
- i3-wm
|
||||
- libasound2-dev
|
||||
- libboost-dev
|
||||
- libfreetype6-dev
|
||||
- libcairo2-dev
|
||||
- libiw-dev
|
||||
- libmpdclient-dev
|
||||
- libxcb-ewmh-dev
|
||||
|
18
README.md
18
README.md
@ -68,8 +68,8 @@ A [pull-request has been submitted](https://github.com/voidlinux/void-packages/p
|
||||
### Dependencies
|
||||
|
||||
A compiler with C++14 support ([clang-3.4+](http://llvm.org/releases/download.html), [gcc-5.1+](https://gcc.gnu.org/releases.html)).
|
||||
- cmake
|
||||
- libXft
|
||||
- cairo
|
||||
- libxcb
|
||||
- python2
|
||||
- xcb-proto
|
||||
- xcb-util-image
|
||||
@ -77,11 +77,11 @@ A compiler with C++14 support ([clang-3.4+](http://llvm.org/releases/download.ht
|
||||
- xcb-util-xrm
|
||||
|
||||
Optional dependencies for extended module support:
|
||||
- alsa-lib (required by `internal/volume`)
|
||||
- jsoncpp (required by `internal/i3`)
|
||||
- libmpdclient (required by `internal/mpd`)
|
||||
- libcurl (required by `internal/github`)
|
||||
- wireless_tools (required by `internal/network`)
|
||||
- alsa-lib *required by `internal/volume`*
|
||||
- jsoncpp *required by `internal/i3`*
|
||||
- libmpdclient *required by `internal/mpd`*
|
||||
- libcurl *required by `internal/github`*
|
||||
- wireless_tools *required by `internal/network`*
|
||||
|
||||
Find a more complete list on the [dedicated wiki page](https://github.com/jaagr/polybar/wiki/Compiling).
|
||||
|
||||
@ -119,10 +119,6 @@ Details on how to setup and configure the bar and each module have been moved to
|
||||
$ polybar example
|
||||
~~~
|
||||
|
||||
**NOTE:** If the bar output looks odd, it's probably because you're
|
||||
missing the fonts defined in the config. Update the config or install the
|
||||
missing fonts.
|
||||
|
||||
|
||||
### Running
|
||||
|
||||
|
@ -66,12 +66,12 @@ option(ENABLE_I3 "Enable i3 support" ON)
|
||||
option(ENABLE_MPD "Enable mpd support" ON)
|
||||
option(ENABLE_NETWORK "Enable network support" ON)
|
||||
|
||||
option(WITH_XRANDR "XRANDR support" ON)
|
||||
option(WITH_XRENDER "XRENDER support" OFF)
|
||||
option(WITH_XDAMAGE "XDAMAGE support" OFF)
|
||||
option(WITH_XSYNC "XSYNC support" OFF)
|
||||
option(WITH_XCOMPOSITE "XCOMPOSITE support" OFF)
|
||||
option(WITH_XKB "XKB support" ON)
|
||||
option(WITH_XRANDR "xcb-randr support" ON)
|
||||
option(WITH_XRENDER "xcb-render support" OFF)
|
||||
option(WITH_XDAMAGE "xcb-damage support" OFF)
|
||||
option(WITH_XSYNC "xcb-sync support" OFF)
|
||||
option(WITH_XCOMPOSITE "xcb-composite support" OFF)
|
||||
option(WITH_XKB "xcb-xkb support" ON)
|
||||
option(WITH_XRM "xcb-xrm support" ON)
|
||||
|
||||
if(NOT DEFINED WITH_XRM)
|
||||
|
@ -62,14 +62,14 @@ colored_option(STATUS " i3" ENABLE_I3 "32;1" "37;2")
|
||||
colored_option(STATUS " mpd" ENABLE_MPD "32;1" "37;2")
|
||||
colored_option(STATUS " network" ENABLE_NETWORK "32;1" "37;2")
|
||||
message(STATUS " X extensions:")
|
||||
colored_option(STATUS " XRandR" WITH_XRANDR "32;1" "37;2")
|
||||
colored_option(STATUS " XRandR (enable monitors)" ENABLE_XRANDR_MONITORS "32;1" "37;2")
|
||||
colored_option(STATUS " XRender" WITH_XRENDER "32;1" "37;2")
|
||||
colored_option(STATUS " XDamage" WITH_XDAMAGE "32;1" "37;2")
|
||||
colored_option(STATUS " XSync" WITH_XSYNC "32;1" "37;2")
|
||||
colored_option(STATUS " XComposite" WITH_XCOMPOSITE "32;1" "37;2")
|
||||
colored_option(STATUS " Xkb" WITH_XKB "32;1" "37;2")
|
||||
colored_option(STATUS " Xrm" WITH_XRM "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-randr" WITH_XRANDR "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-randr (monitor support)" ENABLE_XRANDR_MONITORS "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-render" WITH_XRENDER "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-damage" WITH_XDAMAGE "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-sync" WITH_XSYNC "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-composite" WITH_XCOMPOSITE "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-xkb" WITH_XKB "32;1" "37;2")
|
||||
colored_option(STATUS " xcb-xrm" WITH_XRM "32;1" "37;2")
|
||||
|
||||
if(CMAKE_BUILD_TYPE_LOWER STREQUAL "debug")
|
||||
message(STATUS " Debug options:")
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "events/signal_fwd.hpp"
|
||||
#include "events/signal_receiver.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/types.hpp"
|
||||
#include "x11/window.hpp"
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "events/signal_receiver.hpp"
|
||||
#include "events/types.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/types.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "components/types.hpp"
|
||||
#include "events/signal_emitter.hpp"
|
||||
#include "events/signal_fwd.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/extensions/randr.hpp"
|
||||
#include "x11/types.hpp"
|
||||
#include "x11/window.hpp"
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "modules/meta/event_handler.hpp"
|
||||
#include "modules/meta/input_handler.hpp"
|
||||
#include "modules/meta/static_module.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/extensions/xkb.hpp"
|
||||
#include "x11/window.hpp"
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "modules/meta/event_handler.hpp"
|
||||
#include "modules/meta/static_module.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/ewmh.hpp"
|
||||
#include "x11/icccm.hpp"
|
||||
#include "x11/window.hpp"
|
||||
@ -18,7 +17,7 @@ namespace modules {
|
||||
~active_window();
|
||||
|
||||
bool match(const xcb_window_t win) const;
|
||||
string title(xcb_ewmh_connection_t* ewmh) const;
|
||||
string title() const;
|
||||
|
||||
private:
|
||||
xcb_connection_t* m_connection{nullptr};
|
||||
@ -43,7 +42,6 @@ namespace modules {
|
||||
static constexpr const char* TAG_LABEL{"<label>"};
|
||||
|
||||
connection& m_connection;
|
||||
ewmh_connection_t m_ewmh;
|
||||
unique_ptr<active_window> m_active;
|
||||
label_t m_label;
|
||||
};
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "modules/meta/event_handler.hpp"
|
||||
#include "modules/meta/input_handler.hpp"
|
||||
#include "modules/meta/static_module.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/ewmh.hpp"
|
||||
#include "x11/icccm.hpp"
|
||||
#include "x11/window.hpp"
|
||||
|
@ -102,7 +102,7 @@ const auto print_build_info = [](bool extended = false) {
|
||||
(ENABLE_NETWORK ? '+' : '-'));
|
||||
if (extended) {
|
||||
printf("\n");
|
||||
printf("X extensions: %cxrandr (%cmonitors) %cxrender %cxdamage %cxsync %cxcomposite %cxkb %cxcb-util-xrm\n",
|
||||
printf("X extensions: %crandr (%cmonitors) %crender %cdamage %csync %ccomposite %cxkb %cxrm\n",
|
||||
(WITH_XRANDR ? '+' : '-'),
|
||||
(ENABLE_XRANDR_MONITORS ? '+' : '-'),
|
||||
(WITH_XRENDER ? '+' : '-'),
|
||||
|
@ -1,16 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <cstdlib>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xpp/core.hpp>
|
||||
#include <xpp/generic/factory.hpp>
|
||||
#include <xpp/proto/x.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/screen.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/extensions/all.hpp"
|
||||
#include "x11/registry.hpp"
|
||||
#include "x11/types.hpp"
|
||||
@ -18,19 +14,6 @@
|
||||
POLYBAR_NS
|
||||
|
||||
namespace detail {
|
||||
class displaylock {
|
||||
public:
|
||||
explicit displaylock(Display* display) : m_display(forward<decltype(display)>(display)) {
|
||||
XLockDisplay(m_display);
|
||||
}
|
||||
~displaylock() {
|
||||
XUnlockDisplay(m_display);
|
||||
}
|
||||
|
||||
protected:
|
||||
Display* m_display;
|
||||
};
|
||||
|
||||
template <typename Connection, typename... Extensions>
|
||||
class interfaces : public xpp::x::extension::interface<interfaces<Connection, Extensions...>, Connection>,
|
||||
public Extensions::template interface<interfaces<Connection, Extensions...>, Connection>... {
|
||||
@ -49,12 +32,12 @@ namespace detail {
|
||||
private Extensions...,
|
||||
private Extensions::error_dispatcher... {
|
||||
public:
|
||||
template <typename... Args>
|
||||
explicit connection_base(Args&&... args)
|
||||
: xpp::core(forward<Args>(args)...)
|
||||
explicit connection_base(xcb_connection_t* c, int s)
|
||||
: xpp::core(c)
|
||||
, interfaces<connection_base<Derived, Extensions...>, Extensions...>(*this)
|
||||
, Extensions(m_c.get())...
|
||||
, Extensions::error_dispatcher(static_cast<Extensions&>(*this).get())... {
|
||||
core::m_screen = s;
|
||||
m_root_window = screen_of_display(default_screen())->root;
|
||||
}
|
||||
|
||||
@ -116,9 +99,9 @@ class connection : public detail::connection_base<connection&, XPP_EXTENSION_LIS
|
||||
using base_type = detail::connection_base<connection&, XPP_EXTENSION_LIST>;
|
||||
|
||||
using make_type = connection&;
|
||||
static make_type make(Display* display = nullptr);
|
||||
static make_type make(xcb_connection_t* conn = nullptr, int default_screen = 0);
|
||||
|
||||
explicit connection(Display* dsp);
|
||||
explicit connection(xcb_connection_t* c, int default_screen);
|
||||
~connection();
|
||||
|
||||
const connection& operator=(const connection& o) {
|
||||
@ -130,8 +113,6 @@ class connection : public detail::connection_base<connection&, XPP_EXTENSION_LIS
|
||||
static void pack_values(unsigned int mask, const xcb_params_gc_t* src, unsigned int* dest);
|
||||
static void pack_values(unsigned int mask, const xcb_params_configure_window_t* src, unsigned int* dest);
|
||||
|
||||
operator Display*() const;
|
||||
Visual* visual(unsigned char depth = 32U);
|
||||
xcb_screen_t* screen(bool realloc = false);
|
||||
|
||||
string id(xcb_window_t w) const;
|
||||
@ -145,6 +126,8 @@ class connection : public detail::connection_base<connection&, XPP_EXTENSION_LIS
|
||||
|
||||
xcb_visualtype_t* visual_type(xcb_screen_t* screen, int match_depth = 32);
|
||||
|
||||
bool root_pixmap(xcb_pixmap_t* pixmap, int* depth, xcb_rectangle_t* rect);
|
||||
|
||||
static string error_str(int error_code);
|
||||
|
||||
void dispatch_event(const shared_ptr<xcb_generic_event_t>& evt) const;
|
||||
@ -181,8 +164,6 @@ class connection : public detail::connection_base<connection&, XPP_EXTENSION_LIS
|
||||
}
|
||||
|
||||
protected:
|
||||
Display* m_display{nullptr};
|
||||
map<unsigned char, Visual*> m_visual;
|
||||
registry m_registry{*this};
|
||||
xcb_screen_t* m_screen{nullptr};
|
||||
};
|
||||
|
@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xpp/event.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
class connection;
|
||||
|
||||
namespace evt {
|
||||
// window focus events
|
||||
using focus_in = xpp::x::event::focus_in<connection&>;
|
||||
using focus_out = xpp::x::event::focus_out<connection&>;
|
||||
|
||||
// cursor events
|
||||
using enter_notify = xpp::x::event::enter_notify<connection&>;
|
||||
using leave_notify = xpp::x::event::leave_notify<connection&>;
|
||||
using motion_notify = xpp::x::event::motion_notify<connection&>;
|
||||
|
||||
// keyboard events
|
||||
using button_press = xpp::x::event::button_press<connection&>;
|
||||
using button_release = xpp::x::event::button_release<connection&>;
|
||||
using key_press = xpp::x::event::key_press<connection&>;
|
||||
using key_release = xpp::x::event::key_release<connection&>;
|
||||
using keymap_notify = xpp::x::event::keymap_notify<connection&>;
|
||||
|
||||
// render events
|
||||
using circulate_notify = xpp::x::event::circulate_notify<connection&>;
|
||||
using circulate_request = xpp::x::event::circulate_request<connection&>;
|
||||
using colormap_notify = xpp::x::event::colormap_notify<connection&>;
|
||||
using configure_notify = xpp::x::event::configure_notify<connection&>;
|
||||
using configure_request = xpp::x::event::configure_request<connection&>;
|
||||
using create_notify = xpp::x::event::create_notify<connection&>;
|
||||
using destroy_notify = xpp::x::event::destroy_notify<connection&>;
|
||||
using expose = xpp::x::event::expose<connection&>;
|
||||
using graphics_exposure = xpp::x::event::graphics_exposure<connection&>;
|
||||
using gravity_notify = xpp::x::event::gravity_notify<connection&>;
|
||||
using map_notify = xpp::x::event::map_notify<connection&>;
|
||||
using map_request = xpp::x::event::map_request<connection&>;
|
||||
using mapping_notify = xpp::x::event::mapping_notify<connection&>;
|
||||
using no_exposure = xpp::x::event::no_exposure<connection&>;
|
||||
using reparent_notify = xpp::x::event::reparent_notify<connection&>;
|
||||
using resize_request = xpp::x::event::resize_request<connection&>;
|
||||
using unmap_notify = xpp::x::event::unmap_notify<connection&>;
|
||||
using visibility_notify = xpp::x::event::visibility_notify<connection&>;
|
||||
|
||||
// data events
|
||||
using client_message = xpp::x::event::client_message<connection&>;
|
||||
using ge_generic = xpp::x::event::ge_generic<connection&>;
|
||||
using property_notify = xpp::x::event::property_notify<connection&>;
|
||||
|
||||
// selection events
|
||||
using selection_clear = xpp::x::event::selection_clear<connection&>;
|
||||
using selection_notify = xpp::x::event::selection_notify<connection&>;
|
||||
using selection_request = xpp::x::event::selection_request<connection&>;
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -14,19 +14,26 @@ using ewmh_connection_t = malloc_ptr_t<xcb_ewmh_connection_t>;
|
||||
namespace ewmh_util {
|
||||
ewmh_connection_t initialize();
|
||||
|
||||
bool supports(xcb_ewmh_connection_t* ewmh, xcb_atom_t atom, int screen = 0);
|
||||
bool supports(xcb_atom_t atom, int screen = 0);
|
||||
|
||||
string get_wm_name(xcb_ewmh_connection_t* conn, xcb_window_t win);
|
||||
string get_visible_name(xcb_ewmh_connection_t* conn, xcb_window_t win);
|
||||
string get_icon_name(xcb_ewmh_connection_t* conn, xcb_window_t win);
|
||||
string get_wm_name(xcb_window_t win);
|
||||
string get_visible_name(xcb_window_t win);
|
||||
string get_icon_name(xcb_window_t win);
|
||||
string get_reply_string(xcb_ewmh_get_utf8_strings_reply_t* reply);
|
||||
|
||||
vector<position> get_desktop_viewports(xcb_ewmh_connection_t* conn, int screen = 0);
|
||||
vector<string> get_desktop_names(xcb_ewmh_connection_t* conn, int screen = 0);
|
||||
unsigned int get_current_desktop(xcb_ewmh_connection_t* conn, int screen = 0);
|
||||
xcb_window_t get_active_window(xcb_ewmh_connection_t* conn, int screen = 0);
|
||||
vector<position> get_desktop_viewports(int screen = 0);
|
||||
vector<string> get_desktop_names(int screen = 0);
|
||||
unsigned int get_current_desktop(int screen = 0);
|
||||
xcb_window_t get_active_window(int screen = 0);
|
||||
|
||||
void change_current_desktop(xcb_ewmh_connection_t* conn, unsigned int desktop);
|
||||
void change_current_desktop(unsigned int desktop);
|
||||
|
||||
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types);
|
||||
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states);
|
||||
void set_wm_pid(xcb_window_t win);
|
||||
void set_wm_pid(xcb_window_t win, unsigned int pid);
|
||||
void set_wm_desktop(xcb_window_t win, unsigned int desktop = -1u);
|
||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace {
|
||||
inline bool operator==(const xcb_rectangle_t& a, const xcb_rectangle_t& b) {
|
||||
return a.width == b.width && a.height == b.height && a.x == b.x && a.y == b.y;
|
||||
}
|
||||
inline bool operator!=(const xcb_rectangle_t& a, const xcb_rectangle_t& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
inline bool operator==(const xcb_rectangle_t& a, int b) {
|
||||
return a.width == b && a.height == b && a.x == b && a.y == b;
|
||||
}
|
||||
inline bool operator!=(const xcb_rectangle_t& a, int b) {
|
||||
return !(a == b);
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace graphics_util {
|
||||
struct root_pixmap {
|
||||
unsigned char depth{0};
|
||||
unsigned short int width{0};
|
||||
unsigned short int height{0};
|
||||
short int x{0};
|
||||
short int y{0};
|
||||
xcb_pixmap_t pixmap{0};
|
||||
};
|
||||
|
||||
bool create_window(connection& conn, xcb_window_t* win, short int x = 0, short int y = 0, unsigned short int w = 1, unsigned short int h = 1,
|
||||
xcb_window_t root = 0);
|
||||
bool create_pixmap(connection& conn, xcb_drawable_t dst, unsigned short int w, unsigned short int h, xcb_pixmap_t* pixmap);
|
||||
bool create_pixmap(connection& conn, xcb_drawable_t dst, unsigned short int w, unsigned short int h, unsigned char d, xcb_pixmap_t* pixmap);
|
||||
bool create_gc(connection& conn, xcb_drawable_t drawable, xcb_gcontext_t* gc);
|
||||
|
||||
bool get_root_pixmap(connection& conn, root_pixmap* rpix);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -7,8 +7,11 @@
|
||||
POLYBAR_NS
|
||||
|
||||
namespace icccm_util {
|
||||
string get_wm_name(xcb_connection_t* conn, xcb_window_t win);
|
||||
string get_wm_name(xcb_connection_t* c, xcb_window_t w);
|
||||
string get_reply_string(xcb_icccm_get_text_property_reply_t* reply);
|
||||
|
||||
void set_wm_name(xcb_connection_t* c, xcb_window_t w, const char* wmname, size_t l, const char* wmclass, size_t l2);
|
||||
void set_wm_protocols(xcb_connection_t* c, xcb_window_t w, vector<xcb_atom_t> flags);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,18 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/logger.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "events/signal_emitter.hpp"
|
||||
#include "events/signal_fwd.hpp"
|
||||
#include "events/signal_receiver.hpp"
|
||||
#include "utils/concurrency.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/graphics.hpp"
|
||||
#include "x11/tray_client.hpp"
|
||||
|
||||
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
|
||||
@ -142,7 +139,11 @@ class tray_manager : public xpp::event::sink<evt::expose, evt::visibility_notify
|
||||
|
||||
xcb_gcontext_t m_gc{0};
|
||||
xcb_pixmap_t m_pixmap{0};
|
||||
graphics_util::root_pixmap m_rootpixmap{};
|
||||
|
||||
xcb_pixmap_t m_rootpixmap{0};
|
||||
int m_rootpixmap_depth{0};
|
||||
xcb_rectangle_t m_rootpixmap_geom{0, 0, 0U, 0U};
|
||||
|
||||
unsigned int m_prevwidth{0};
|
||||
unsigned int m_prevheight{0};
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <xpp/event.hpp>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
namespace xpp {
|
||||
@ -36,4 +38,47 @@ using atom = xpp::atom<connection&>;
|
||||
using font = xpp::font<connection&>;
|
||||
using cursor = xpp::cursor<connection&>;
|
||||
|
||||
namespace evt {
|
||||
// window focus events
|
||||
using focus_in = xpp::x::event::focus_in<connection&>;
|
||||
using focus_out = xpp::x::event::focus_out<connection&>;
|
||||
// cursor events
|
||||
using enter_notify = xpp::x::event::enter_notify<connection&>;
|
||||
using leave_notify = xpp::x::event::leave_notify<connection&>;
|
||||
using motion_notify = xpp::x::event::motion_notify<connection&>;
|
||||
// keyboard events
|
||||
using button_press = xpp::x::event::button_press<connection&>;
|
||||
using button_release = xpp::x::event::button_release<connection&>;
|
||||
using key_press = xpp::x::event::key_press<connection&>;
|
||||
using key_release = xpp::x::event::key_release<connection&>;
|
||||
using keymap_notify = xpp::x::event::keymap_notify<connection&>;
|
||||
// render events
|
||||
using circulate_notify = xpp::x::event::circulate_notify<connection&>;
|
||||
using circulate_request = xpp::x::event::circulate_request<connection&>;
|
||||
using colormap_notify = xpp::x::event::colormap_notify<connection&>;
|
||||
using configure_notify = xpp::x::event::configure_notify<connection&>;
|
||||
using configure_request = xpp::x::event::configure_request<connection&>;
|
||||
using create_notify = xpp::x::event::create_notify<connection&>;
|
||||
using destroy_notify = xpp::x::event::destroy_notify<connection&>;
|
||||
using expose = xpp::x::event::expose<connection&>;
|
||||
using graphics_exposure = xpp::x::event::graphics_exposure<connection&>;
|
||||
using gravity_notify = xpp::x::event::gravity_notify<connection&>;
|
||||
using map_notify = xpp::x::event::map_notify<connection&>;
|
||||
using map_request = xpp::x::event::map_request<connection&>;
|
||||
using mapping_notify = xpp::x::event::mapping_notify<connection&>;
|
||||
using no_exposure = xpp::x::event::no_exposure<connection&>;
|
||||
using reparent_notify = xpp::x::event::reparent_notify<connection&>;
|
||||
using resize_request = xpp::x::event::resize_request<connection&>;
|
||||
using unmap_notify = xpp::x::event::unmap_notify<connection&>;
|
||||
using visibility_notify = xpp::x::event::visibility_notify<connection&>;
|
||||
// data events
|
||||
using client_message = xpp::x::event::client_message<connection&>;
|
||||
using ge_generic = xpp::x::event::ge_generic<connection&>;
|
||||
using property_notify = xpp::x::event::property_notify<connection&>;
|
||||
// selection events
|
||||
using selection_clear = xpp::x::event::selection_clear<connection&>;
|
||||
using selection_notify = xpp::x::event::selection_notify<connection&>;
|
||||
using selection_request = xpp::x::event::selection_request<connection&>;
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -16,19 +16,9 @@ class window : public xpp::window<connection&> {
|
||||
|
||||
window& operator=(const xcb_window_t win);
|
||||
|
||||
window create_checked(
|
||||
short int x, short int y, unsigned short int w, unsigned short int h, unsigned int mask = 0, const xcb_params_cw_t* p = nullptr);
|
||||
|
||||
window change_event_mask(unsigned int mask);
|
||||
window ensure_event_mask(unsigned int event);
|
||||
|
||||
window reconfigure_geom(unsigned short int w, unsigned short int h, short int x = 0, short int y = 0);
|
||||
window reconfigure_pos(short int x, short int y);
|
||||
window reconfigure_struts(unsigned short int w, unsigned short int h, short int x, bool bottom = false);
|
||||
|
||||
void redraw();
|
||||
|
||||
void visibility_notify(xcb_visibility_t state);
|
||||
};
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace wm_util {
|
||||
void set_wm_name(xcb_connection_t* conn, xcb_window_t win, const string& wm_name, const string& wm_class);
|
||||
void set_wm_protocols(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> flags);
|
||||
void set_wm_window_type(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> types);
|
||||
void set_wm_state(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> states);
|
||||
void set_wm_pid(xcb_connection_t* conn, xcb_window_t win, pid_t pid);
|
||||
void set_wm_desktop(xcb_connection_t* conn, xcb_window_t win, unsigned int desktop = -1u);
|
||||
void set_wm_window_opacity(xcb_connection_t* conn, xcb_window_t win, unsigned long int values);
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
|
||||
|
@ -10,18 +10,14 @@ list(REMOVE_ITEM SOURCES ipc.cpp)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(PkgConfig)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(X11_XCB REQUIRED)
|
||||
pkg_check_modules(CAIRO REQUIRED cairo-fc)
|
||||
# pkg_check_modules(PANGOCAIRO REQUIRED pangocairo)
|
||||
|
||||
set(APP_LIBRARIES ${APP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
# set(APP_LIBRARIES ${APP_LIBRARIES} ${PANGOCAIRO_LIBRARIES})
|
||||
set(APP_LIBRARIES ${APP_LIBRARIES} ${CAIRO_LIBRARIES})
|
||||
|
||||
set(APP_INCLUDE_DIRS ${APP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include)
|
||||
set(APP_INCLUDE_DIRS ${APP_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/lib/concurrentqueue/include)
|
||||
set(APP_INCLUDE_DIRS ${APP_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
# set(APP_INCLUDE_DIRS ${APP_INCLUDE_DIRS} ${PANGOCAIRO_INCLUDE_DIRS})
|
||||
set(APP_INCLUDE_DIRS ${APP_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS})
|
||||
|
||||
# xpp library
|
||||
@ -147,9 +143,7 @@ make_executable(${PROJECT_NAME} SOURCES
|
||||
target_link_libraries(${PROJECT_NAME} Threads::Threads)
|
||||
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC
|
||||
$<$<CXX_COMPILER_ID:GNU>:$<$<CONFIG:MinSizeRel>:-flto>>
|
||||
${X11_XCB_DEFINITIONS}
|
||||
${XCB_DEFINITIONS})
|
||||
$<$<CXX_COMPILER_ID:GNU>:$<$<CONFIG:MinSizeRel>:-flto>>)
|
||||
|
||||
# }}}
|
||||
# Create executable target: ipc messager {{{
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "components/bar.hpp"
|
||||
@ -17,9 +16,10 @@
|
||||
#include "utils/string.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/ewmh.hpp"
|
||||
#include "x11/extensions/all.hpp"
|
||||
#include "x11/icccm.hpp"
|
||||
#include "x11/tray_manager.hpp"
|
||||
#include "x11/wm.hpp"
|
||||
|
||||
#if ENABLE_I3
|
||||
#include "utils/i3.hpp"
|
||||
@ -28,7 +28,6 @@
|
||||
POLYBAR_NS
|
||||
|
||||
using namespace signals::ui;
|
||||
using namespace wm_util;
|
||||
|
||||
/**
|
||||
* Create instance
|
||||
@ -436,21 +435,22 @@ void bar::reconfigure_struts() {
|
||||
* Reconfigure window wm hint values
|
||||
*/
|
||||
void bar::reconfigure_wm_hints() {
|
||||
const auto& win = m_opts.window;
|
||||
|
||||
m_log.trace("bar: Set window WM_NAME");
|
||||
xcb_icccm_set_wm_name(m_connection, m_opts.window, XCB_ATOM_STRING, 8, m_opts.wmname.size(), m_opts.wmname.c_str());
|
||||
xcb_icccm_set_wm_class(m_connection, m_opts.window, 15, "polybar\0Polybar");
|
||||
icccm_util::set_wm_name(m_connection, win, m_opts.wmname.c_str(), m_opts.wmname.size(), "polybar\0Polybar", 15_z);
|
||||
|
||||
m_log.trace("bar: Set window _NET_WM_WINDOW_TYPE");
|
||||
set_wm_window_type(m_connection, m_opts.window, {_NET_WM_WINDOW_TYPE_DOCK});
|
||||
ewmh_util::set_wm_window_type(win, {_NET_WM_WINDOW_TYPE_DOCK});
|
||||
|
||||
m_log.trace("bar: Set window _NET_WM_STATE");
|
||||
set_wm_state(m_connection, m_opts.window, {_NET_WM_STATE_STICKY, _NET_WM_STATE_ABOVE});
|
||||
ewmh_util::set_wm_state(win, {_NET_WM_STATE_STICKY, _NET_WM_STATE_ABOVE});
|
||||
|
||||
m_log.trace("bar: Set window _NET_WM_DESKTOP");
|
||||
set_wm_desktop(m_connection, m_opts.window, 0xFFFFFFFF);
|
||||
ewmh_util::set_wm_desktop(win, 0xFFFFFFFF);
|
||||
|
||||
m_log.trace("bar: Set window _NET_WM_PID");
|
||||
set_wm_pid(m_connection, m_opts.window, getpid());
|
||||
ewmh_util::set_wm_pid(win);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -785,8 +785,7 @@ bool bar::on(const signals::ui::tick&) {
|
||||
|
||||
bool bar::on(const signals::ui::dim_window& sig) {
|
||||
m_opts.dimmed = sig.cast() != 1.0;
|
||||
set_wm_window_opacity(m_connection, m_opts.window, sig.cast() * 0xFFFFFFFF);
|
||||
m_connection.flush();
|
||||
ewmh_util::set_wm_window_opacity(m_opts.window, sig.cast() * 0xFFFFFFFF);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "components/types.hpp"
|
||||
#include "events/signal.hpp"
|
||||
#include "events/signal_emitter.hpp"
|
||||
#include "events/signal_receiver.hpp"
|
||||
#include "modules/meta/event_handler.hpp"
|
||||
#include "modules/meta/factory.hpp"
|
||||
#include "utils/command.hpp"
|
||||
@ -18,13 +17,10 @@
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/extensions/all.hpp"
|
||||
#include "x11/tray_manager.hpp"
|
||||
#include "x11/types.hpp"
|
||||
|
||||
#include <csignal>
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
array<int, 2> g_eventpipe{{-1, -1}};
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/extensions/all.hpp"
|
||||
#include "x11/generic.hpp"
|
||||
#include "x11/winspec.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "events/signal.hpp"
|
||||
#include "events/signal_emitter.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/events.hpp"
|
||||
#include "x11/extensions/all.hpp"
|
||||
#include "x11/registry.hpp"
|
||||
#include "x11/types.hpp"
|
||||
|
14
src/main.cpp
14
src/main.cpp
@ -67,15 +67,17 @@ int main(int argc, char** argv) {
|
||||
//==================================================
|
||||
// Connect to X server
|
||||
//==================================================
|
||||
XInitThreads();
|
||||
Display* xdisplay{XOpenDisplay(nullptr)};
|
||||
auto xcb_error = 0;
|
||||
auto xcb_screen = 0;
|
||||
auto xcb_connection = xcb_connect(nullptr, &xcb_screen);
|
||||
|
||||
if (xdisplay == nullptr) {
|
||||
logger.err("A connection to X could not be established... ");
|
||||
return EXIT_FAILURE;
|
||||
if (xcb_connection == nullptr) {
|
||||
throw application_error("A connection to X could not be established...");
|
||||
} else if ((xcb_error = xcb_connection_has_error(xcb_connection))) {
|
||||
throw application_error("X connection error... (what: " + connection::error_str(xcb_error) + ")");
|
||||
}
|
||||
|
||||
connection& conn{connection::make(xdisplay)};
|
||||
connection& conn{connection::make(xcb_connection, xcb_screen)};
|
||||
conn.ensure_event_mask(conn.root(), XCB_EVENT_MASK_PROPERTY_CHANGE);
|
||||
|
||||
//==================================================
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "drawtypes/ramp.hpp"
|
||||
#include "utils/math.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/graphics.hpp"
|
||||
#include "x11/winspec.hpp"
|
||||
|
||||
#include "modules/meta/base.inl"
|
||||
|
||||
@ -48,9 +48,12 @@ namespace modules {
|
||||
}
|
||||
|
||||
// Create window that will proxy all RandR notify events
|
||||
if (!graphics_util::create_window(m_connection, &m_proxy, -1, -1, 1, 1)) {
|
||||
throw module_error("Failed to create event proxy");
|
||||
}
|
||||
// clang-format off
|
||||
m_proxy = winspec(m_connection)
|
||||
<< cw_size(1, 1)
|
||||
<< cw_pos(-1, -1)
|
||||
<< cw_flush(true);
|
||||
// clang-format on
|
||||
|
||||
// Connect with the event registry and make sure we get
|
||||
// notified when a RandR output property gets modified
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "utils/factory.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/graphics.hpp"
|
||||
|
||||
#include "modules/meta/base.inl"
|
||||
|
||||
@ -45,12 +44,12 @@ namespace modules {
|
||||
* _NET_WM_NAME
|
||||
* _NET_WM_VISIBLE_NAME
|
||||
*/
|
||||
string active_window::title(xcb_ewmh_connection_t* ewmh) const {
|
||||
string active_window::title() const {
|
||||
string title;
|
||||
|
||||
if (!(title = ewmh_util::get_wm_name(ewmh, m_window)).empty()) {
|
||||
if (!(title = ewmh_util::get_wm_name(m_window)).empty()) {
|
||||
return title;
|
||||
} else if (!(title = ewmh_util::get_visible_name(ewmh, m_window)).empty()) {
|
||||
} else if (!(title = ewmh_util::get_visible_name(m_window)).empty()) {
|
||||
return title;
|
||||
} else if (!(title = icccm_util::get_wm_name(m_connection, m_window)).empty()) {
|
||||
return title;
|
||||
@ -65,12 +64,12 @@ namespace modules {
|
||||
xwindow_module::xwindow_module(const bar_settings& bar, string name_)
|
||||
: static_module<xwindow_module>(bar, move(name_)), m_connection(connection::make()) {
|
||||
// Initialize ewmh atoms
|
||||
if ((m_ewmh = ewmh_util::initialize()) == nullptr) {
|
||||
if ((ewmh_util::initialize()) == nullptr) {
|
||||
throw module_error("Failed to initialize ewmh atoms");
|
||||
}
|
||||
|
||||
// Check if the WM supports _NET_ACTIVE_WINDOW
|
||||
if (!ewmh_util::supports(m_ewmh.get(), _NET_ACTIVE_WINDOW)) {
|
||||
if (!ewmh_util::supports(_NET_ACTIVE_WINDOW)) {
|
||||
throw module_error("The WM does not list _NET_ACTIVE_WINDOW as a supported hint");
|
||||
}
|
||||
|
||||
@ -109,13 +108,13 @@ namespace modules {
|
||||
m_active.reset();
|
||||
}
|
||||
|
||||
if (!m_active && (win = ewmh_util::get_active_window(&*m_ewmh)) != XCB_NONE) {
|
||||
if (!m_active && (win = ewmh_util::get_active_window()) != XCB_NONE) {
|
||||
m_active = make_unique<active_window>(m_connection, win);
|
||||
}
|
||||
|
||||
if (m_label) {
|
||||
m_label->reset_tokens();
|
||||
m_label->replace_token("%title%", m_active ? m_active->title(&*m_ewmh) : "");
|
||||
m_label->replace_token("%title%", m_active ? m_active->title() : "");
|
||||
}
|
||||
|
||||
broadcast();
|
||||
|
@ -31,12 +31,12 @@ namespace modules {
|
||||
}
|
||||
|
||||
// Check if the WM supports _NET_CURRENT_DESKTOP
|
||||
if (!ewmh_util::supports(m_ewmh.get(), m_ewmh->_NET_CURRENT_DESKTOP)) {
|
||||
if (!ewmh_util::supports(m_ewmh->_NET_CURRENT_DESKTOP)) {
|
||||
throw module_error("The WM does not support _NET_CURRENT_DESKTOP, aborting...");
|
||||
}
|
||||
|
||||
// Check if the WM supports _NET_DESKTOP_VIEWPORT
|
||||
if (!ewmh_util::supports(m_ewmh.get(), m_ewmh->_NET_DESKTOP_VIEWPORT) && m_pinworkspaces) {
|
||||
if (!ewmh_util::supports(m_ewmh->_NET_DESKTOP_VIEWPORT) && m_pinworkspaces) {
|
||||
throw module_error("The WM does not support _NET_DESKTOP_VIEWPORT (required when `pin-workspaces = true`)");
|
||||
} else if (!m_pinworkspaces) {
|
||||
m_monitorsupport = false;
|
||||
@ -96,14 +96,14 @@ namespace modules {
|
||||
* Fetch and parse data
|
||||
*/
|
||||
void xworkspaces_module::update() {
|
||||
auto current = ewmh_util::get_current_desktop(m_ewmh.get());
|
||||
auto names = ewmh_util::get_desktop_names(m_ewmh.get());
|
||||
auto current = ewmh_util::get_current_desktop();
|
||||
auto names = ewmh_util::get_desktop_names();
|
||||
vector<position> viewports;
|
||||
size_t num{0};
|
||||
position pos{};
|
||||
|
||||
if (m_monitorsupport) {
|
||||
viewports = ewmh_util::get_desktop_viewports(m_ewmh.get());
|
||||
viewports = ewmh_util::get_desktop_viewports();
|
||||
num = math_util::min(names.size(), viewports.size());
|
||||
} else {
|
||||
num = names.size();
|
||||
@ -215,7 +215,7 @@ namespace modules {
|
||||
unsigned int new_desktop{0};
|
||||
unsigned int min_desktop{0};
|
||||
unsigned int max_desktop{0};
|
||||
unsigned int current_desktop{ewmh_util::get_current_desktop(m_ewmh.get())};
|
||||
unsigned int current_desktop{ewmh_util::get_current_desktop()};
|
||||
|
||||
for (auto&& viewport : m_viewports) {
|
||||
for (auto&& desktop : viewport->desktops) {
|
||||
@ -245,7 +245,7 @@ namespace modules {
|
||||
|
||||
if (new_desktop != current_desktop) {
|
||||
m_log.info("%s: Requesting change to desktop #%u", name(), new_desktop);
|
||||
ewmh_util::change_current_desktop(m_ewmh.get(), new_desktop);
|
||||
ewmh_util::change_current_desktop(new_desktop);
|
||||
m_connection.flush();
|
||||
} else {
|
||||
m_log.info("%s: Ignoring change to current desktop", name());
|
||||
|
@ -42,14 +42,12 @@ namespace i3_util {
|
||||
* Get main root window
|
||||
*/
|
||||
xcb_window_t root_window(connection& conn) {
|
||||
auto ewmh = ewmh_util::initialize();
|
||||
auto children = conn.query_tree(conn.screen()->root).children();
|
||||
|
||||
const auto wm_name = [&](xcb_ewmh_connection_t* ewmh, xcb_window_t win) -> string {
|
||||
const auto wm_name = [&](xcb_connection_t* conn, xcb_window_t win) -> string {
|
||||
string title;
|
||||
if (!(title = ewmh_util::get_wm_name(ewmh, win)).empty()) {
|
||||
if (!(title = ewmh_util::get_wm_name(win)).empty()) {
|
||||
return title;
|
||||
} else if (!(title = icccm_util::get_wm_name(ewmh->connection, win)).empty()) {
|
||||
} else if (!(title = icccm_util::get_wm_name(conn, win)).empty()) {
|
||||
return title;
|
||||
} else {
|
||||
return "";
|
||||
@ -57,7 +55,7 @@ namespace i3_util {
|
||||
};
|
||||
|
||||
for (auto it = children.begin(); it != children.end(); it++) {
|
||||
if (wm_name(&*ewmh, *it) == "i3") {
|
||||
if (wm_name(conn, *it) == "i3") {
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
@ -13,14 +13,12 @@ POLYBAR_NS
|
||||
/**
|
||||
* Create instance
|
||||
*/
|
||||
connection::make_type connection::make(Display* display) {
|
||||
connection::make_type connection::make(xcb_connection_t* conn, int default_screen) {
|
||||
return static_cast<connection::make_type>(
|
||||
*factory_util::singleton<std::remove_reference_t<connection::make_type>>(display));
|
||||
*factory_util::singleton<std::remove_reference_t<connection::make_type>>(conn, default_screen));
|
||||
}
|
||||
|
||||
connection::connection(Display* dsp) : base_type(XGetXCBConnection(dsp)), m_display(dsp) {
|
||||
XSetEventQueueOwner(m_display, XCBOwnsEventQueue);
|
||||
|
||||
connection::connection(xcb_connection_t* c, int default_screen) : base_type(c, default_screen) {
|
||||
// Preload required xcb atoms {{{
|
||||
|
||||
vector<xcb_intern_atom_cookie_t> cookies(memory_util::countof(ATOMS));
|
||||
@ -62,13 +60,7 @@ connection::connection(Display* dsp) : base_type(XGetXCBConnection(dsp)), m_disp
|
||||
}
|
||||
|
||||
connection::~connection() {
|
||||
if (m_display != nullptr) {
|
||||
XCloseDisplay(m_display);
|
||||
} else {
|
||||
disconnect();
|
||||
std::for_each(m_visual.begin(), m_visual.end(), [=](pair<unsigned char, Visual*> p) { XFree(p.second); });
|
||||
m_visual.clear();
|
||||
}
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void connection::pack_values(unsigned int mask, const unsigned int* src, unsigned int* dest) {
|
||||
@ -88,21 +80,6 @@ void connection::pack_values(unsigned int mask, const xcb_params_configure_windo
|
||||
pack_values(mask, reinterpret_cast<const unsigned int*>(src), dest);
|
||||
}
|
||||
|
||||
connection::operator Display*() const {
|
||||
return m_display;
|
||||
}
|
||||
|
||||
Visual* connection::visual(unsigned char depth) {
|
||||
auto visual_it = m_visual.find(depth);
|
||||
if (visual_it == m_visual.end()) {
|
||||
XVisualInfo info{};
|
||||
if (XMatchVisualInfo(*this, default_screen(), depth, TrueColor, &info)) {
|
||||
visual_it = m_visual.emplace_hint(visual_it, depth, info.visual);
|
||||
}
|
||||
}
|
||||
return visual_it->second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create X window id string
|
||||
*/
|
||||
@ -188,6 +165,38 @@ xcb_visualtype_t* connection::visual_type(xcb_screen_t* screen, int match_depth)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query root window pixmap
|
||||
*/
|
||||
bool connection::root_pixmap(xcb_pixmap_t* pixmap, int* depth, xcb_rectangle_t* rect) {
|
||||
const xcb_atom_t pixmap_properties[3]{ESETROOT_PMAP_ID, _XROOTMAP_ID, _XSETROOT_ID};
|
||||
for (auto&& property : pixmap_properties) {
|
||||
try {
|
||||
auto prop = get_property(false, screen()->root, property, XCB_ATOM_PIXMAP, 0L, 1L);
|
||||
if (prop->format == 32 && prop->value_len == 1) {
|
||||
*pixmap = *prop.value<xcb_pixmap_t>().begin();
|
||||
}
|
||||
} catch (const exception& err) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (*pixmap) {
|
||||
try {
|
||||
auto geom = get_geometry(*pixmap);
|
||||
*depth = geom->depth;
|
||||
rect->width = geom->width;
|
||||
rect->height = geom->height;
|
||||
rect->x = geom->x;
|
||||
rect->y = geom->y;
|
||||
return true;
|
||||
} catch (const exception& err) {
|
||||
*pixmap = XCB_NONE;
|
||||
*rect = xcb_rectangle_t{0, 0, 0U, 0U};
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse connection error
|
||||
*/
|
||||
|
158
src/x11/ewmh.cpp
158
src/x11/ewmh.cpp
@ -1,6 +1,9 @@
|
||||
#include "x11/ewmh.hpp"
|
||||
#include <unistd.h>
|
||||
|
||||
#include "components/types.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/ewmh.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
@ -15,31 +18,28 @@ namespace ewmh_util {
|
||||
return g_connection;
|
||||
}
|
||||
|
||||
bool supports(xcb_ewmh_connection_t* ewmh, xcb_atom_t atom, int screen) {
|
||||
bool supports(xcb_atom_t atom, int screen) {
|
||||
auto conn = initialize().get();
|
||||
bool supports{false};
|
||||
|
||||
xcb_ewmh_get_atoms_reply_t reply{};
|
||||
reply.atoms = nullptr;
|
||||
|
||||
if (!xcb_ewmh_get_supported_reply(ewmh, xcb_ewmh_get_supported(ewmh, screen), &reply, nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < reply.atoms_len; ++n) {
|
||||
if (reply.atoms[n] == atom) {
|
||||
supports = true;
|
||||
break;
|
||||
if (xcb_ewmh_get_supported_reply(conn, xcb_ewmh_get_supported(conn, screen), &reply, nullptr)) {
|
||||
for (size_t n = 0; n < reply.atoms_len; ++n) {
|
||||
if (reply.atoms[n] == atom) {
|
||||
supports = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (reply.atoms != nullptr) {
|
||||
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||
}
|
||||
}
|
||||
|
||||
if (reply.atoms != nullptr) {
|
||||
xcb_ewmh_get_atoms_reply_wipe(&reply);
|
||||
}
|
||||
|
||||
return supports;
|
||||
}
|
||||
|
||||
string get_wm_name(xcb_ewmh_connection_t* conn, xcb_window_t win) {
|
||||
string get_wm_name(xcb_window_t win) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||
if (xcb_ewmh_get_wm_name_reply(conn, xcb_ewmh_get_wm_name(conn, win), &utf8_reply, nullptr)) {
|
||||
return get_reply_string(&utf8_reply);
|
||||
@ -47,7 +47,8 @@ namespace ewmh_util {
|
||||
return "";
|
||||
}
|
||||
|
||||
string get_visible_name(xcb_ewmh_connection_t* conn, xcb_window_t win) {
|
||||
string get_visible_name(xcb_window_t win) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||
if (xcb_ewmh_get_wm_visible_name_reply(conn, xcb_ewmh_get_wm_visible_name(conn, win), &utf8_reply, nullptr)) {
|
||||
return get_reply_string(&utf8_reply);
|
||||
@ -55,7 +56,8 @@ namespace ewmh_util {
|
||||
return "";
|
||||
}
|
||||
|
||||
string get_icon_name(xcb_ewmh_connection_t* conn, xcb_window_t win) {
|
||||
string get_icon_name(xcb_window_t win) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_get_utf8_strings_reply_t utf8_reply{};
|
||||
if (xcb_ewmh_get_wm_icon_name_reply(conn, xcb_ewmh_get_wm_icon_name(conn, win), &utf8_reply, nullptr)) {
|
||||
return get_reply_string(&utf8_reply);
|
||||
@ -64,75 +66,103 @@ namespace ewmh_util {
|
||||
}
|
||||
|
||||
string get_reply_string(xcb_ewmh_get_utf8_strings_reply_t* reply) {
|
||||
if (reply == nullptr) {
|
||||
return "";
|
||||
string str;
|
||||
if (reply) {
|
||||
str = string(reply->strings, reply->strings_len);
|
||||
xcb_ewmh_get_utf8_strings_reply_wipe(reply);
|
||||
}
|
||||
string str(reply->strings, reply->strings_len);
|
||||
xcb_ewmh_get_utf8_strings_reply_wipe(reply);
|
||||
return str;
|
||||
}
|
||||
|
||||
unsigned int get_current_desktop(xcb_ewmh_connection_t* conn, int screen) {
|
||||
unsigned int desktop{0};
|
||||
if (xcb_ewmh_get_current_desktop_reply(conn, xcb_ewmh_get_current_desktop(conn, screen), &desktop, nullptr)) {
|
||||
return desktop;
|
||||
}
|
||||
return XCB_NONE;
|
||||
unsigned int get_current_desktop(int screen) {
|
||||
auto conn = initialize().get();
|
||||
unsigned int desktop = XCB_NONE;
|
||||
xcb_ewmh_get_current_desktop_reply(conn, xcb_ewmh_get_current_desktop(conn, screen), &desktop, nullptr);
|
||||
return desktop;
|
||||
}
|
||||
|
||||
vector<position> get_desktop_viewports(xcb_ewmh_connection_t* conn, int screen) {
|
||||
vector<position> get_desktop_viewports(int screen) {
|
||||
auto conn = initialize().get();
|
||||
vector<position> viewports;
|
||||
xcb_ewmh_get_desktop_viewport_reply_t reply{};
|
||||
|
||||
if (!xcb_ewmh_get_desktop_viewport_reply(conn, xcb_ewmh_get_desktop_viewport(conn, screen), &reply, nullptr)) {
|
||||
return viewports;
|
||||
if (xcb_ewmh_get_desktop_viewport_reply(conn, xcb_ewmh_get_desktop_viewport(conn, screen), &reply, nullptr)) {
|
||||
for (size_t n = 0; n < reply.desktop_viewport_len; n++) {
|
||||
viewports.emplace_back(position{
|
||||
static_cast<short int>(reply.desktop_viewport[n].x), static_cast<short int>(reply.desktop_viewport[n].y)});
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < reply.desktop_viewport_len; n++) {
|
||||
viewports.emplace_back(position{
|
||||
static_cast<short int>(reply.desktop_viewport[n].x), static_cast<short int>(reply.desktop_viewport[n].y)});
|
||||
}
|
||||
|
||||
return viewports;
|
||||
}
|
||||
|
||||
vector<string> get_desktop_names(xcb_ewmh_connection_t* conn, int screen) {
|
||||
vector<string> get_desktop_names(int screen) {
|
||||
auto conn = initialize().get();
|
||||
vector<string> names;
|
||||
xcb_ewmh_get_utf8_strings_reply_t reply{};
|
||||
|
||||
if (!xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
||||
return names;
|
||||
}
|
||||
|
||||
char buffer[BUFSIZ];
|
||||
size_t len{0};
|
||||
|
||||
for (size_t n = 0; n < reply.strings_len; n++) {
|
||||
if (reply.strings[n] == '\0') {
|
||||
if (xcb_ewmh_get_desktop_names_reply(conn, xcb_ewmh_get_desktop_names(conn, screen), &reply, nullptr)) {
|
||||
char buffer[BUFSIZ];
|
||||
size_t len{0};
|
||||
for (size_t n = 0; n < reply.strings_len; n++) {
|
||||
if (reply.strings[n] == '\0') {
|
||||
names.emplace_back(buffer, len);
|
||||
len = 0;
|
||||
} else {
|
||||
buffer[len++] = reply.strings[n];
|
||||
}
|
||||
}
|
||||
if (len) {
|
||||
names.emplace_back(buffer, len);
|
||||
len = 0;
|
||||
} else {
|
||||
buffer[len++] = reply.strings[n];
|
||||
}
|
||||
}
|
||||
|
||||
if (len) {
|
||||
names.emplace_back(buffer, len);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
xcb_window_t get_active_window(xcb_ewmh_connection_t* conn, int screen) {
|
||||
xcb_window_t win{0};
|
||||
if (!xcb_ewmh_get_active_window_reply(conn, xcb_ewmh_get_active_window(conn, screen), &win, nullptr)) {
|
||||
return XCB_NONE;
|
||||
}
|
||||
xcb_window_t get_active_window(int screen) {
|
||||
auto conn = initialize().get();
|
||||
unsigned int win = XCB_NONE;
|
||||
xcb_ewmh_get_active_window_reply(conn, xcb_ewmh_get_active_window(conn, screen), &win, nullptr);
|
||||
return win;
|
||||
}
|
||||
|
||||
void change_current_desktop(xcb_ewmh_connection_t* conn, unsigned int desktop) {
|
||||
void change_current_desktop(unsigned int desktop) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_request_change_current_desktop(conn, 0, desktop, XCB_CURRENT_TIME);
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_window_type(xcb_window_t win, vector<xcb_atom_t> types) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_window_type(conn, win, types.size(), types.data());
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_state(xcb_window_t win, vector<xcb_atom_t> states) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_state(conn, win, states.size(), states.data());
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_pid(xcb_window_t win) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_pid(conn, win, getpid());
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_pid(xcb_window_t win, unsigned int pid) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_pid(conn, win, pid);
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_desktop(xcb_window_t win, unsigned int desktop) {
|
||||
auto conn = initialize().get();
|
||||
xcb_ewmh_set_wm_desktop(conn, win, desktop);
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
|
||||
void set_wm_window_opacity(xcb_window_t win, unsigned long int values) {
|
||||
auto conn = initialize().get();
|
||||
xcb_change_property(conn->connection, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
||||
xcb_flush(conn->connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,119 +0,0 @@
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#include <xcb/xcb_util.h>
|
||||
|
||||
#include "errors.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/graphics.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace graphics_util {
|
||||
/**
|
||||
* Create a basic window
|
||||
*/
|
||||
bool create_window(connection& conn, xcb_window_t* win, short int x, short int y, unsigned short int w,
|
||||
unsigned short int h, xcb_window_t root) {
|
||||
if (!root) {
|
||||
root = conn.screen()->root;
|
||||
}
|
||||
|
||||
try {
|
||||
auto copy = XCB_COPY_FROM_PARENT;
|
||||
*win = conn.generate_id();
|
||||
conn.create_window_checked(copy, *win, root, x, y, w, h, 0, copy, copy, 0, nullptr);
|
||||
return true;
|
||||
} catch (const exception& err) {
|
||||
*win = XCB_NONE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic pixmap with the same depth as the
|
||||
* root depth of the default screen
|
||||
*/
|
||||
bool create_pixmap(
|
||||
connection& conn, xcb_drawable_t dst, unsigned short int w, unsigned short int h, xcb_pixmap_t* pixmap) {
|
||||
return graphics_util::create_pixmap(conn, dst, w, h, conn.screen()->root_depth, pixmap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic pixmap with specific depth
|
||||
*/
|
||||
bool create_pixmap(connection& conn, xcb_drawable_t dst, unsigned short int w, unsigned short int h, unsigned char d,
|
||||
xcb_pixmap_t* pixmap) {
|
||||
try {
|
||||
*pixmap = conn.generate_id();
|
||||
conn.create_pixmap_checked(d, *pixmap, dst, w, h);
|
||||
return true;
|
||||
} catch (const exception& err) {
|
||||
*pixmap = XCB_NONE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic gc
|
||||
*/
|
||||
bool create_gc(connection& conn, xcb_drawable_t drawable, xcb_gcontext_t* gc) {
|
||||
try {
|
||||
xcb_params_gc_t params{};
|
||||
|
||||
unsigned int mask = 0;
|
||||
unsigned int values[32];
|
||||
|
||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, graphics_exposures, 1);
|
||||
connection::pack_values(mask, ¶ms, values);
|
||||
|
||||
*gc = conn.generate_id();
|
||||
conn.create_gc_checked(*gc, drawable, mask, values);
|
||||
return true;
|
||||
} catch (const exception& err) {
|
||||
*gc = XCB_NONE;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for the root window pixmap
|
||||
*/
|
||||
bool get_root_pixmap(connection& conn, root_pixmap* rpix) {
|
||||
auto screen = conn.screen();
|
||||
const xcb_atom_t pixmap_properties[3]{ESETROOT_PMAP_ID, _XROOTMAP_ID, _XSETROOT_ID};
|
||||
for (auto&& property : pixmap_properties) {
|
||||
auto cookie = xcb_get_property(conn, false, screen->root, property, XCB_ATOM_PIXMAP, 0L, 1L);
|
||||
auto reply = xcb_get_property_reply(conn, cookie, nullptr);
|
||||
|
||||
if (reply && reply->format == 32 && reply->value_len == 1) {
|
||||
rpix->pixmap = *static_cast<xcb_pixmap_t*>(xcb_get_property_value(reply));
|
||||
}
|
||||
}
|
||||
|
||||
if (!rpix->pixmap) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto cookie = xcb_get_geometry(conn, rpix->pixmap);
|
||||
auto reply = xcb_get_geometry_reply(conn, cookie, nullptr);
|
||||
|
||||
if (!reply) {
|
||||
rpix->pixmap = XCB_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
rpix->depth = reply->depth;
|
||||
rpix->width = reply->width;
|
||||
rpix->height = reply->height;
|
||||
rpix->x = reply->x;
|
||||
rpix->y = reply->y;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -1,24 +1,34 @@
|
||||
#include "x11/icccm.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace icccm_util {
|
||||
string get_wm_name(xcb_connection_t* conn, xcb_window_t win) {
|
||||
string get_wm_name(xcb_connection_t* c, xcb_window_t w) {
|
||||
xcb_icccm_get_text_property_reply_t reply{};
|
||||
if (xcb_icccm_get_wm_name_reply(conn, xcb_icccm_get_wm_name(conn, win), &reply, nullptr)) {
|
||||
if (xcb_icccm_get_wm_name_reply(c, xcb_icccm_get_wm_name(c, w), &reply, nullptr)) {
|
||||
return get_reply_string(&reply);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
string get_reply_string(xcb_icccm_get_text_property_reply_t* reply) {
|
||||
if (reply->name == nullptr) {
|
||||
return "";
|
||||
string str;
|
||||
if (reply) {
|
||||
str = string(reply->name, reply->name_len);
|
||||
xcb_icccm_get_text_property_reply_wipe(reply);
|
||||
}
|
||||
string str(reply->name, reply->name_len);
|
||||
xcb_icccm_get_text_property_reply_wipe(reply);
|
||||
return str;
|
||||
}
|
||||
|
||||
void set_wm_name(xcb_connection_t* c, xcb_window_t w, const char* wmname, size_t l, const char* wmclass, size_t l2) {
|
||||
xcb_icccm_set_wm_name(c, w, XCB_ATOM_STRING, 8, l, wmname);
|
||||
xcb_icccm_set_wm_class(c, w, l2, wmclass);
|
||||
}
|
||||
|
||||
void set_wm_protocols(xcb_connection_t* c, xcb_window_t w, vector<xcb_atom_t> flags) {
|
||||
xcb_icccm_set_wm_protocols(c, w, WM_PROTOCOLS, flags.size(), flags.data());
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,9 +1,7 @@
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#include <xcb/xcb_image.h>
|
||||
#include <thread>
|
||||
|
||||
#include "components/config.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "errors.hpp"
|
||||
#include "events/signal.hpp"
|
||||
#include "utils/color.hpp"
|
||||
@ -13,11 +11,11 @@
|
||||
#include "utils/process.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/graphics.hpp"
|
||||
#include "x11/ewmh.hpp"
|
||||
#include "x11/icccm.hpp"
|
||||
#include "x11/tray_manager.hpp"
|
||||
#include "x11/window.hpp"
|
||||
#include "x11/winspec.hpp"
|
||||
#include "x11/wm.hpp"
|
||||
#include "x11/xembed.hpp"
|
||||
#include "x11/xresources.hpp"
|
||||
|
||||
@ -38,8 +36,6 @@
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
using namespace wm_util;
|
||||
|
||||
/**
|
||||
* Create instance
|
||||
*/
|
||||
@ -272,7 +268,7 @@ void tray_manager::deactivate(bool clear_selection) {
|
||||
m_tray = 0;
|
||||
m_pixmap = 0;
|
||||
m_gc = 0;
|
||||
m_rootpixmap.pixmap = 0;
|
||||
m_rootpixmap = 0;
|
||||
m_prevwidth = 0;
|
||||
m_prevheight = 0;
|
||||
m_opts.configured_x = 0;
|
||||
@ -400,7 +396,7 @@ void tray_manager::reconfigure_clients() {
|
||||
void tray_manager::reconfigure_bg(bool realloc) {
|
||||
if (!m_opts.transparent || m_clients.empty() || !m_mapped) {
|
||||
return;
|
||||
} else if (!m_rootpixmap.pixmap) {
|
||||
} else if (!m_rootpixmap) {
|
||||
realloc = true;
|
||||
}
|
||||
|
||||
@ -413,16 +409,16 @@ void tray_manager::reconfigure_bg(bool realloc) {
|
||||
|
||||
m_log.trace("tray: Reconfigure bg (realloc=%i)", realloc);
|
||||
|
||||
if (realloc && !get_root_pixmap(m_connection, &m_rootpixmap)) {
|
||||
if (realloc && !m_connection.root_pixmap(&m_rootpixmap, &m_rootpixmap_depth, &m_rootpixmap_geom)) {
|
||||
return m_log.err("Failed to get root pixmap for tray background (realloc=%i)", realloc);
|
||||
} else if (realloc) {
|
||||
// clang-format off
|
||||
m_log.info("Tray root pixmap (rootpmap=%s, geom=%dx%d+%d+%d, tray=%s, pmap=%s, gc=%s)",
|
||||
m_connection.id(m_rootpixmap.pixmap),
|
||||
m_rootpixmap.width,
|
||||
m_rootpixmap.height,
|
||||
m_rootpixmap.x,
|
||||
m_rootpixmap.y,
|
||||
m_connection.id(m_rootpixmap),
|
||||
m_rootpixmap_geom.width,
|
||||
m_rootpixmap_geom.height,
|
||||
m_rootpixmap_geom.x,
|
||||
m_rootpixmap_geom.y,
|
||||
m_connection.id(m_tray),
|
||||
m_connection.id(m_pixmap),
|
||||
m_connection.id(m_gc));
|
||||
@ -434,15 +430,15 @@ void tray_manager::reconfigure_bg(bool realloc) {
|
||||
|
||||
auto x = calculate_x(w);
|
||||
auto y = calculate_y();
|
||||
auto px = math_util::max(0, m_rootpixmap.x + x);
|
||||
auto py = math_util::max(0, m_rootpixmap.y + y);
|
||||
auto px = math_util::max(0, m_rootpixmap_geom.x + x);
|
||||
auto py = math_util::max(0, m_rootpixmap_geom.y + y);
|
||||
|
||||
// Make sure we don't try to copy void content
|
||||
if (px + w > m_rootpixmap.width) {
|
||||
w -= px + w - m_rootpixmap.width;
|
||||
if (px + w > m_rootpixmap_geom.width) {
|
||||
w -= px + w - m_rootpixmap_geom.width;
|
||||
}
|
||||
if (py + h > m_rootpixmap.height) {
|
||||
h -= py + h - m_rootpixmap.height;
|
||||
if (py + h > m_rootpixmap_geom.height) {
|
||||
h -= py + h - m_rootpixmap_geom.height;
|
||||
}
|
||||
|
||||
if (realloc) {
|
||||
@ -450,8 +446,7 @@ void tray_manager::reconfigure_bg(bool realloc) {
|
||||
unsigned char image_depth;
|
||||
|
||||
try {
|
||||
auto image_reply =
|
||||
m_connection.get_image(XCB_IMAGE_FORMAT_Z_PIXMAP, m_rootpixmap.pixmap, px, py, w, h, XCB_COPY_PLANE);
|
||||
auto image_reply = m_connection.get_image(XCB_IMAGE_FORMAT_Z_PIXMAP, m_rootpixmap, px, py, w, h, XCB_COPY_PLANE);
|
||||
image_depth = image_reply->depth;
|
||||
std::back_insert_iterator<decltype(image_data)> back_it(image_data);
|
||||
std::copy(image_reply.data().begin(), image_reply.data().end(), back_it);
|
||||
@ -469,7 +464,7 @@ void tray_manager::reconfigure_bg(bool realloc) {
|
||||
}
|
||||
}
|
||||
|
||||
m_connection.copy_area_checked(m_rootpixmap.pixmap, m_pixmap, m_gc, px, py, 0, 0, w, h);
|
||||
m_connection.copy_area_checked(m_rootpixmap, m_pixmap, m_gc, px, py, 0, 0, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -487,7 +482,7 @@ void tray_manager::refresh_window() {
|
||||
auto width = calculate_w();
|
||||
auto height = calculate_h();
|
||||
|
||||
if (m_opts.transparent && !m_rootpixmap.pixmap) {
|
||||
if (m_opts.transparent && !m_rootpixmap) {
|
||||
xcb_rectangle_t rect{0, 0, static_cast<uint16_t>(width), static_cast<uint16_t>(height)};
|
||||
m_connection.poly_fill_rectangle(m_pixmap, m_gc, 1, &rect);
|
||||
}
|
||||
@ -571,7 +566,7 @@ void tray_manager::create_bg(bool realloc) {
|
||||
if (!m_opts.transparent) {
|
||||
return;
|
||||
}
|
||||
if (!realloc && m_pixmap && m_gc && m_rootpixmap.pixmap) {
|
||||
if (!realloc && m_pixmap && m_gc && m_rootpixmap) {
|
||||
return;
|
||||
}
|
||||
if (realloc && m_pixmap) {
|
||||
@ -586,10 +581,27 @@ void tray_manager::create_bg(bool realloc) {
|
||||
auto w = m_opts.width_max;
|
||||
auto h = calculate_h();
|
||||
|
||||
if (!m_pixmap && !graphics_util::create_pixmap(m_connection, m_tray, w, h, &m_pixmap)) {
|
||||
return m_log.err("Failed to create pixmap for tray background");
|
||||
} else if (!m_gc && !graphics_util::create_gc(m_connection, m_pixmap, &m_gc)) {
|
||||
return m_log.err("Failed to create gcontext for tray background");
|
||||
if (!m_pixmap) {
|
||||
try {
|
||||
m_pixmap = m_connection.generate_id();
|
||||
m_connection.create_pixmap_checked(m_connection.screen()->root_depth, m_pixmap, m_tray, w, h);
|
||||
} catch (const exception& err) {
|
||||
return m_log.err("Failed to create pixmap for tray background (err: %s)", err.what());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_gc) {
|
||||
try {
|
||||
xcb_params_gc_t params{};
|
||||
unsigned int mask = 0;
|
||||
unsigned int values[32];
|
||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, graphics_exposures, 1);
|
||||
connection::pack_values(mask, ¶ms, values);
|
||||
m_gc = m_connection.generate_id();
|
||||
m_connection.create_gc_checked(m_gc, m_pixmap, mask, values);
|
||||
} catch (const exception& err) {
|
||||
return m_log.err("Failed to create gcontext for tray background (err: %s)", err.what());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@ -632,21 +644,20 @@ void tray_manager::set_wm_hints() {
|
||||
const unsigned int visual{m_connection.screen()->root_visual};
|
||||
const unsigned int orientation{_NET_SYSTEM_TRAY_ORIENTATION_HORZ};
|
||||
|
||||
m_log.trace("tray: Set window WM_NAME / WM_CLASS", m_connection.id(m_tray));
|
||||
xcb_icccm_set_wm_name(m_connection, m_tray, XCB_ATOM_STRING, 8, 19, TRAY_WM_NAME);
|
||||
xcb_icccm_set_wm_class(m_connection, m_tray, 12, TRAY_WM_CLASS);
|
||||
m_log.trace("bar: Set window WM_NAME / WM_CLASS");
|
||||
icccm_util::set_wm_name(m_connection, m_tray, TRAY_WM_NAME, 19_z, TRAY_WM_CLASS, 12_z);
|
||||
|
||||
m_log.trace("tray: Set window WM_PROTOCOLS");
|
||||
set_wm_protocols(m_connection, m_tray, {WM_DELETE_WINDOW, WM_TAKE_FOCUS});
|
||||
icccm_util::set_wm_protocols(m_connection, m_tray, {WM_DELETE_WINDOW, WM_TAKE_FOCUS});
|
||||
|
||||
m_log.trace("tray: Set window _NET_WM_WINDOW_TYPE");
|
||||
set_wm_window_type(m_connection, m_tray, {_NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_NORMAL});
|
||||
ewmh_util::set_wm_window_type(m_tray, {_NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_NORMAL});
|
||||
|
||||
m_log.trace("tray: Set window _NET_WM_STATE");
|
||||
set_wm_state(m_connection, m_tray, {_NET_WM_STATE_SKIP_TASKBAR});
|
||||
ewmh_util::set_wm_state(m_tray, {_NET_WM_STATE_SKIP_TASKBAR});
|
||||
|
||||
m_log.trace("tray: Set window _NET_WM_PID");
|
||||
set_wm_pid(m_connection, m_tray, getpid());
|
||||
ewmh_util::set_wm_pid(m_tray);
|
||||
|
||||
m_log.trace("tray: Set window _NET_SYSTEM_TRAY_VISUAL");
|
||||
xcb_change_property(
|
||||
@ -1148,8 +1159,7 @@ bool tray_manager::on(const visibility_change& evt) {
|
||||
|
||||
bool tray_manager::on(const dim_window& evt) {
|
||||
if (m_activated) {
|
||||
wm_util::set_wm_window_opacity(m_connection, m_tray, evt.cast() * 0xFFFFFFFF);
|
||||
m_connection.flush();
|
||||
ewmh_util::set_wm_window_opacity(m_tray, evt.cast() * 0xFFFFFFFF);
|
||||
}
|
||||
// let the event bubble
|
||||
return false;
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
#include "components/types.hpp"
|
||||
#include "utils/memory.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
@ -10,41 +8,7 @@
|
||||
POLYBAR_NS
|
||||
|
||||
window& window::operator=(const xcb_window_t win) {
|
||||
*this = window{connection(), win};
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create window and check for errors
|
||||
*/
|
||||
window window::create_checked(
|
||||
short int x, short int y, unsigned short int w, unsigned short int h, unsigned int mask, const xcb_params_cw_t* p) {
|
||||
if (*this == XCB_NONE) {
|
||||
*this = connection().generate_id();
|
||||
}
|
||||
|
||||
auto root = connection().screen()->root;
|
||||
auto copy = XCB_COPY_FROM_PARENT;
|
||||
unsigned int values[16]{0};
|
||||
connection::pack_values(mask, p, values);
|
||||
connection().create_window_checked(copy, *this, root, x, y, w, h, 0, copy, copy, mask, values);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the window event mask
|
||||
*/
|
||||
window window::change_event_mask(unsigned int mask) {
|
||||
change_attributes_checked(XCB_CW_EVENT_MASK, &mask);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add given event to the event mask unless already added
|
||||
*/
|
||||
window window::ensure_event_mask(unsigned int event) {
|
||||
connection().ensure_event_mask(*this, event);
|
||||
resource(connection(), win);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -108,26 +72,4 @@ window window::reconfigure_struts(unsigned short int w, unsigned short int h, sh
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger redraw by toggling visibility state
|
||||
*/
|
||||
void window::redraw() {
|
||||
visibility_notify(XCB_VISIBILITY_FULLY_OBSCURED);
|
||||
visibility_notify(XCB_VISIBILITY_UNOBSCURED);
|
||||
connection().flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send visibility notify event
|
||||
*/
|
||||
void window::visibility_notify(xcb_visibility_t state) {
|
||||
auto notify = memory_util::make_malloc_ptr<xcb_visibility_notify_event_t, 32_z>();
|
||||
notify->response_type = XCB_VISIBILITY_NOTIFY;
|
||||
notify->window = *this;
|
||||
notify->state = state;
|
||||
|
||||
unsigned int mask{XCB_EVENT_MASK_NO_EVENT};
|
||||
connection().send_event(false, *this, mask, reinterpret_cast<const char*>(notify.get()));
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -1,5 +1,3 @@
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "x11/connection.hpp"
|
||||
#include "x11/winspec.hpp"
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
#include <unistd.h>
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
#include "utils/math.hpp"
|
||||
#include "x11/atoms.hpp"
|
||||
#include "x11/wm.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace wm_util {
|
||||
void set_wm_name(xcb_connection_t* conn, xcb_window_t win, const string& wm_name, const string& wm_class) {
|
||||
xcb_icccm_set_wm_name(conn, win, XCB_ATOM_STRING, 8, wm_name.length(), wm_name.c_str());
|
||||
xcb_icccm_set_wm_class(conn, win, wm_class.length(), wm_class.c_str());
|
||||
}
|
||||
|
||||
void set_wm_protocols(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> flags) {
|
||||
xcb_icccm_set_wm_protocols(conn, win, WM_PROTOCOLS, flags.size(), flags.data());
|
||||
}
|
||||
|
||||
void set_wm_window_type(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> types) {
|
||||
xcb_change_property(
|
||||
conn, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_TYPE, XCB_ATOM_ATOM, 32, types.size(), types.data());
|
||||
}
|
||||
|
||||
void set_wm_state(xcb_connection_t* conn, xcb_window_t win, vector<xcb_atom_t> states) {
|
||||
xcb_change_property(
|
||||
conn, XCB_PROP_MODE_REPLACE, win, _NET_WM_STATE, XCB_ATOM_ATOM, 32, states.size(), states.data());
|
||||
}
|
||||
|
||||
void set_wm_pid(xcb_connection_t* conn, xcb_window_t win, pid_t pid) {
|
||||
pid = getpid();
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, _NET_WM_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
|
||||
}
|
||||
|
||||
void set_wm_desktop(xcb_connection_t* conn, xcb_window_t win, unsigned int desktop) {
|
||||
const unsigned int value_list[1]{desktop};
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, _NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, value_list);
|
||||
}
|
||||
|
||||
void set_wm_window_opacity(xcb_connection_t* conn, xcb_window_t win, unsigned long int values) {
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, _NET_WM_WINDOW_OPACITY, XCB_ATOM_CARDINAL, 32, 1, &values);
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
Loading…
Reference in New Issue
Block a user