繁体   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