polybar-dwm/include/x11/tray_manager.hpp

202 lines
5.4 KiB
C++
Raw Normal View History

2016-11-02 19:22:45 +00:00
#pragma once
2021-09-21 18:59:48 +00:00
#include <atomic>
2016-11-25 12:55:15 +00:00
#include <chrono>
#include <memory>
2016-11-02 19:22:45 +00:00
#include "cairo/context.hpp"
#include "cairo/surface.hpp"
2016-11-02 19:22:45 +00:00
#include "common.hpp"
#include "components/logger.hpp"
#include "components/types.hpp"
#include "events/signal_fwd.hpp"
2017-01-24 07:49:27 +00:00
#include "events/signal_receiver.hpp"
2016-11-20 22:04:31 +00:00
#include "utils/concurrency.hpp"
#include "x11/atoms.hpp"
#include "x11/connection.hpp"
#include "x11/tray_client.hpp"
2016-11-02 19:22:45 +00:00
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
2016-11-19 05:22:44 +00:00
#define TRAY_WM_NAME "Polybar tray window"
#define TRAY_WM_CLASS "tray\0Polybar"
2016-11-02 19:22:45 +00:00
2017-01-01 20:28:28 +00:00
#define TRAY_PLACEHOLDER "<placeholder-systray>"
2016-11-19 05:22:44 +00:00
POLYBAR_NS
2016-11-02 19:22:45 +00:00
2016-11-25 12:55:15 +00:00
namespace chrono = std::chrono;
using namespace std::chrono_literals;
2021-09-21 18:59:48 +00:00
using std::atomic;
2016-11-25 12:55:15 +00:00
// fwd declarations
class connection;
class background_manager;
class bg_slice;
enum class tray_postition { NONE = 0, LEFT, CENTER, RIGHT, MODULE };
struct tray_settings {
tray_postition tray_position{tray_postition::NONE};
2017-01-19 10:11:28 +00:00
bool running{false};
2022-02-27 19:30:23 +00:00
2022-02-27 20:36:16 +00:00
/**
* Tray window position.
*
* Relative to the bar window
* TODO make relative to inner area
*/
position pos{0, 0};
/**
* Tray offset in pixels.
*/
position offset{0, 0};
/**
* Current dimensions of the tray window.
*/
size win_size{0, 0};
/**
* Dimensions for client windows.
*/
size client_size{0, 0};
/**
* Number of clients currently mapped.
*/
int num_mapped_clients{0};
2022-02-27 20:36:16 +00:00
// This is the width of the bar window
// TODO directly read from bar_settings
2017-01-25 22:33:26 +00:00
unsigned int width_max{0U};
2022-02-27 20:36:16 +00:00
/**
* Number of pixels added between tray icons
*/
2017-01-25 22:33:26 +00:00
unsigned int spacing{0U};
rgba background{};
rgba foreground{};
bool transparent{false};
2016-12-03 22:01:21 +00:00
bool detached{false};
xcb_window_t bar_window;
};
class tray_manager
: public xpp::event::sink<evt::expose, evt::visibility_notify, evt::client_message, evt::configure_request,
evt::resize_request, evt::selection_clear, evt::property_notify, evt::reparent_notify, evt::destroy_notify,
evt::map_notify, evt::unmap_notify>,
public signal_receiver<SIGN_PRIORITY_TRAY, signals::ui::visibility_change, signals::ui::dim_window,
signals::ui::update_background, signals::ui_tray::tray_pos_change, signals::ui_tray::tray_visibility> {
2016-11-02 19:22:45 +00:00
public:
2016-12-09 08:40:46 +00:00
using make_type = unique_ptr<tray_manager>;
2022-03-07 00:24:15 +00:00
static make_type make(const bar_settings& bar_opts);
2016-12-09 08:02:47 +00:00
explicit tray_manager(connection& conn, signal_emitter& emitter, const logger& logger, background_manager& back,
2022-03-07 00:24:15 +00:00
const bar_settings& bar_opts);
~tray_manager();
2016-11-02 19:22:45 +00:00
const tray_settings settings() const;
2016-11-02 19:22:45 +00:00
void setup(const string& tray_module_name);
2016-11-02 19:22:45 +00:00
void activate();
2016-11-25 12:55:15 +00:00
void activate_delayed(chrono::duration<double, std::milli> delay = 1s);
2016-11-25 03:10:26 +00:00
void deactivate(bool clear_selection = true);
2016-11-02 19:22:45 +00:00
void reconfigure();
2022-04-15 22:20:00 +00:00
void reconfigure_bg();
2016-11-02 19:22:45 +00:00
protected:
void reconfigure_window();
void reconfigure_clients();
void refresh_window();
2022-03-06 22:43:06 +00:00
void redraw_window();
2016-11-02 19:22:45 +00:00
void query_atom();
void create_window();
2022-02-27 19:30:23 +00:00
void create_bg();
void set_wm_hints();
void set_tray_colors();
2016-11-02 19:22:45 +00:00
void acquire_selection();
void notify_clients();
2016-12-14 10:34:09 +00:00
void notify_clients_delayed();
2016-11-02 19:22:45 +00:00
void track_selection_owner(xcb_window_t owner);
void process_docking_request(xcb_window_t win);
int calculate_x(unsigned width) const;
2022-02-27 19:30:23 +00:00
int calculate_y() const;
unsigned short int calculate_w() const;
unsigned short int calculate_h() const;
2016-11-02 19:22:45 +00:00
2017-01-19 10:11:28 +00:00
int calculate_client_y();
2016-11-02 19:22:45 +00:00
bool is_embedded(const xcb_window_t& win) const;
tray_client* find_client(const xcb_window_t& win);
void remove_client(const tray_client& client, bool reconfigure = true);
2016-12-15 02:30:41 +00:00
void remove_client(xcb_window_t win, bool reconfigure = true);
2022-02-27 20:36:16 +00:00
int mapped_clients() const;
bool has_mapped_clients() const;
bool change_visibility(bool visible);
2016-11-02 19:22:45 +00:00
void handle(const evt::expose& evt) override;
void handle(const evt::visibility_notify& evt) override;
void handle(const evt::client_message& evt) override;
void handle(const evt::configure_request& evt) override;
void handle(const evt::resize_request& evt) override;
void handle(const evt::selection_clear& evt) override;
void handle(const evt::property_notify& evt) override;
void handle(const evt::reparent_notify& evt) override;
void handle(const evt::destroy_notify& evt) override;
void handle(const evt::map_notify& evt) override;
void handle(const evt::unmap_notify& evt) override;
bool on(const signals::ui::visibility_change& evt) override;
bool on(const signals::ui::dim_window& evt) override;
bool on(const signals::ui::update_background& evt) override;
bool on(const signals::ui_tray::tray_pos_change& evt) override;
bool on(const signals::ui_tray::tray_visibility& evt) override;
2016-11-02 19:22:45 +00:00
private:
connection& m_connection;
signal_emitter& m_sig;
2016-11-02 19:22:45 +00:00
const logger& m_log;
background_manager& m_background_manager;
std::shared_ptr<bg_slice> m_bg_slice;
vector<tray_client> m_clients;
2016-11-02 19:22:45 +00:00
2016-12-15 08:29:14 +00:00
tray_settings m_opts{};
2022-02-27 19:30:23 +00:00
const bar_settings& m_bar_opts;
2016-11-02 19:22:45 +00:00
xcb_gcontext_t m_gc{0};
xcb_pixmap_t m_pixmap{0};
unique_ptr<cairo::surface> m_surface;
unique_ptr<cairo::context> m_context;
2017-01-24 07:49:27 +00:00
2016-11-02 19:22:45 +00:00
xcb_atom_t m_atom{0};
xcb_window_t m_tray{0};
xcb_window_t m_othermanager{0};
2016-12-23 04:18:58 +00:00
atomic<bool> m_activated{false};
atomic<bool> m_mapped{false};
atomic<bool> m_hidden{false};
atomic<bool> m_acquired_selection{false};
2016-11-02 19:22:45 +00:00
2016-11-25 12:55:15 +00:00
thread m_delaythread;
2016-11-02 19:22:45 +00:00
mutable mutex m_mtx{};
2016-12-14 10:34:09 +00:00
bool m_firstactivation{true};
2016-11-02 19:22:45 +00:00
};
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END