fix(screen): Only reload if changed

This commit is contained in:
Michael Carlberg 2016-12-03 16:44:31 +01:00
parent ef9b37447b
commit 6b51234f23
4 changed files with 26 additions and 4 deletions

View File

@ -36,6 +36,7 @@ class screen : public xpp::event::sink<evt::randr_screen_change_notify> {
xcb_window_t m_root;
xcb_window_t m_proxy{XCB_NONE};
vector<monitor_t> m_monitors;
struct size m_size{0U, 0U};
bool m_sigraised{false};
};

View File

@ -59,7 +59,7 @@ class connection : public xpp_connection {
string id(xcb_window_t w) const;
xcb_screen_t* screen();
xcb_screen_t* screen(bool realloc = false);
void ensure_event_mask(xcb_window_t win, uint32_t event);
void clear_event_mask(xcb_window_t win);

View File

@ -28,6 +28,7 @@ screen::screen(connection& conn, const logger& logger, const config& conf)
, m_log(logger)
, m_conf(conf)
, m_root(conn.root())
, m_monitors(randr_util::get_monitors(m_connection, m_root, true))
, m_size({conn.screen()->width_in_pixels, conn.screen()->height_in_pixels}) {
assert(g_signals::event::enqueue != nullptr);
@ -80,9 +81,29 @@ screen::~screen() {
* If the screen dimensions have changed we raise USR1 to trigger a reload
*/
void screen::handle(const evt::randr_screen_change_notify& evt) {
if (!m_sigraised && evt->request_window == m_proxy) {
if (m_sigraised || evt->request_window != m_proxy) {
return;
}
auto screen = m_connection.screen(true);
auto changed = false;
if (screen->width_in_pixels != m_size.w || screen->height_in_pixels != m_size.h) {
changed = true;
} else {
auto monitors = randr_util::get_monitors(m_connection, m_root, true);
for (size_t n = 0; n < monitors.size(); n++) {
if (n < m_monitors.size() && monitors[n]->output != m_monitors[n]->output) {
changed = true;
}
}
}
if (changed) {
m_log.warn("randr_screen_change_notify (%ux%u)... reloading", evt->width, evt->height);
m_sigraised = true;
quit_event quit{};
quit.reload = true;
g_signals::event::enqueue(reinterpret_cast<const eventloop::entry_t&>(quit));

View File

@ -102,8 +102,8 @@ string connection::id(xcb_window_t w) const {
/**
* Get pointer to the default xcb screen
*/
xcb_screen_t* connection::screen() {
if (m_screen == nullptr) {
xcb_screen_t* connection::screen(bool realloc) {
if (m_screen == nullptr || realloc) {
m_screen = screen_of_display(default_screen());
}
return m_screen;