簡體   English   中英

x11 XChangeProperty 因 BadValue 而失敗

[英]x11 XChangeProperty fails with BadValue

我正在嘗試使用 X11 創建一個全屏窗口。 我設法獲得了一個基本的窗口和事件處理。 根據我必須使用屬性名稱“_MOTIF_WM_HINTS”,以隱藏窗口的裝飾,與自定義類型一起Hints (不管在哪里居住或為用戶創建)。 盡管如此,我在這里找到了一個屬性名稱列表,但是當我嘗試使用像“_WM_NAME”或“_NET_WM_NAME”這樣的簡單名稱時,我收到了BadValue錯誤。

我目前在 Wayland 上,但我確實安裝了xorg-xwayland

具體來說,我收到此錯誤消息:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  18 (X_ChangeProperty)
  Value in failed request:  0x8
  Serial number of failed request:  16
  Current serial number in output stream:  17

有問題的代碼如下:

void fgd_window_toggle_fullscreen(fgd_window_t* win) 
{
    Display* display        = win->dsp; 
    Window   window         = win->window;
    int      screen_id      = win->screen_id;   
    fgd_window_info_t* info = &win->info; 
    
    info->is_fullscreen = (info->is_fullscreen == 1) ? 0 : 1;
    
    if (info->is_fullscreen) 
    {   
        Atom name_property = XInternAtom(display, "_NET_WM_NAME", False); 
        
        if (name_property == None) 
        {
            printf("Failed to create property.\n");
            return;
        }
        
        unsigned char some_text[21] = "My fullscreen window.";
        
        XChangeProperty(display, 
                        window, 
                        name_property, 
                        name_property,
                        PropModeReplace,
                        8,
                        some_text, 
                        10);
        
        int video_modes_count = 0; 
        XF86VidModeModeInfo** infos = NULL;
        
        XF86VidModeGetAllModeLines(display, 
                                                   screen_id, 
                                                   &video_modes_count,
                                                   &infos);
        printf("Number of video modes: %d\n", video_modes_count);
        for (int idx = 0; idx < video_modes_count; idx++) 
        {
            XF86VidModeModeInfo* current_info = infos[idx];
            
            printf("ModeInfo[%d] = (%d, %d)\n", idx, current_info->hdisplay,
                   current_info->vdisplay);
        }
        // Switch to another video mode so we can fullscreen the window.
        XF86VidModeModeInfo* video_mode = *infos;
        XF86VidModeSwitchToMode(display, screen_id, video_mode);
        // Move the window to top left corner.
        XF86VidModeSetViewPort(display, screen_id, 0, 0);
        // Resize the window to the coresponding dimensions.
        XResizeWindow(display, window,info->max_width, info->max_heigth);
        
        XFree(infos);
    }
    else
    {
        int width_center  = (info->max_width  >> 1) - (info->width  >> 1);
        int heigth_center = (info->max_heigth >> 1) - (info->heigth >> 1);
        
        XResizeWindow(display, window, info->width, info->heigth);
        XMoveWindow(display, window, width_center, heigth_center);
    }
    
}

這是與代碼相關的問題還是我的顯示管理器正在干擾?

如果你想最大化窗口,我可以提供另一種方法來做到這一點。

int MaximizeWindow(Window window)
{
    Display *display = XOpenDisplay(NULL);
    XClientMessageEvent ev = {};
    Atom wmState = XInternAtom(display, "_NET_WM_STATE", False);
    Atom maxH = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
    Atom maxV = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False);

    if (wmState == None)
        return 0;

    ev.type = ClientMessage;
    ev.format = 32;
    ev.window = window;
    ev.message_type = wmState;
    ev.data.l[0] = 1;
    ev.data.l[1] = maxH;
    ev.data.l[2] = maxV;
    ev.data.l[3] = 1;

    int rv =  XSendEvent(display, DefaultRootWindow(display), False,
                      SubstructureNotifyMask,
                      (XEvent *)&ev);
    XFlush(display);
    XCloseDisplay(display);
    return rv;
}

窗口句柄作為參數提供給此函數。

我用這個和另一個例子創建了一個git repo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM