[Xcb] RANDR + xcb_screen_t root, the fields (width_in_pixels/height_in_pixels) are not changed

Andrey Af public.irkutsk at gmail.com
Sat Sep 4 06:22:04 UTC 2021


Hi,

After changing the screen size via utility xrandr -s 1 or the  RANDR
API, why does the size information in screen root
width_in_pixels/height_in_pixels not change?

But if I make a new connection, then the information is correct.
How do I update the information in the current connection correctly?

test attachment:
//
// build: g++ -Wall -std=c++17 -I /usr/include/xcb -lxcb -lxcb-randr
test.cpp -o test
//
#include <xcb/xcb.h>
#include <xcb/randr.h>
#include <xcb/xproto.h>

#include <chrono>
#include <thread>
#include <iostream>

using namespace std::chrono_literals;

const xcb_query_extension_reply_t*
 checkRandrExtension(xcb_connection_t* _conn)
{
    auto _randr = xcb_get_extension_data(_conn, &xcb_randr_id);

    if(! _randr || ! _randr->present)
        return nullptr;

    auto cookie = xcb_randr_query_version(_conn,
                                          XCB_RANDR_MAJOR_VERSION,
XCB_RANDR_MINOR_VERSION);
    if(auto reply = xcb_randr_query_version_reply(_conn, cookie, nullptr))
    {
        std::cout << "RANDR extension version: " <<
            reply->major_version << "." << reply->minor_version <<
            ", query version: " << XCB_RANDR_MAJOR_VERSION << "." <<
            XCB_RANDR_MINOR_VERSION << std::endl;

        std::free(reply);
        return _randr;
    }

    return nullptr;
}

int main(int argc, char** argv)
{
    auto _conn = xcb_connect(":0", nullptr);

    if(xcb_connection_has_error(_conn))
        return EXIT_FAILURE;

    if(auto _randr = checkRandrExtension(_conn))
    {
        auto setup = xcb_get_setup(_conn);
        auto _screen = xcb_setup_roots_iterator(setup).data;
        std::cout << "screen size: " << _screen->width_in_pixels <<
"x" << _screen->height_in_pixels << std::endl;

        xcb_randr_select_input(_conn, _screen->root,
            XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE);
        xcb_flush(_conn);

        while(true)
        {
            if(auto ev = xcb_poll_for_event(_conn))
            {
                int type = ev->response_type & ~0x80;

                if(type == _randr->first_event + XCB_RANDR_NOTIFY)
                {
                    auto rn = reinterpret_cast<xcb_randr_notify_event_t*>(ev);
                    if(rn->subCode == XCB_RANDR_NOTIFY_CRTC_CHANGE)
                    {
                        xcb_randr_crtc_change_t cc = rn->u.cc;
                        // window, crtc, mode, rotation, x, y, width, height
                        if(0 < cc.width && 0 < cc.height)
                        {
                            std::cout << "randr crtc change: " <<
                            cc.width << "x" << cc.height << ", screen
size: " <<
                            _screen->width_in_pixels << "x" <<
_screen->height_in_pixels << std::endl;
                        }
                    }
                }

                std::free(ev);
            }
            std::this_thread::sleep_for(1ms);
        }
    }

    xcb_disconnect(_conn);
    return 0;
}


More information about the Xcb mailing list