XLib应用程序只有在调整大小后才重新绘制

3

我有一个使用XLib的C++应用程序。在这个应用程序中,我使用ctime库访问日期和时间,并在Expose事件中创建一个字符串并将其放置在窗口中央。我的问题是,只有当窗口被调整大小时,时间才会更新。例如,除非我不断地调整窗口大小,否则秒数不会改变。以下是代码:

#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <ctime>

int main (int argc, char *argv[])
{
  Display                 *display;
  Visual                  *visual;
  int                     depth;
  int                     text_x;
  int                     text_y;
  XSetWindowAttributes    frame_attributes;
  Window                  frame_window;
  XFontStruct             *fontinfo;
  XGCValues               gr_values;
  GC                      graphical_context;
  XKeyEvent               event;
  char                    contents[80] = "                                                                               ";
  time_t                  rawtime;
  struct tm               *timeinfo;
  int                     contents_length = strlen(contents);

  display = XOpenDisplay(NULL);
  visual = DefaultVisual(display, 0);
  depth  = DefaultDepth(display, 0);

  frame_attributes.background_pixel = XWhitePixel(display, 0);
  /* create the application window */
  frame_window = XCreateWindow(display, XRootWindow(display, 0),
      0, 0, 500, 50, 5, depth,
      InputOutput, visual, CWBackPixel,
      &frame_attributes);
  XStoreName(display, frame_window, "Fly Taskbar");
  XSelectInput(display, frame_window, ExposureMask | StructureNotifyMask);

  fontinfo = XLoadQueryFont(display, "10x20");
  gr_values.font = fontinfo->fid;
  gr_values.foreground = XBlackPixel(display, 0);
  graphical_context = XCreateGC(display, frame_window,
      GCFont+GCForeground, &gr_values);
  XMapWindow(display, frame_window);

  while ( 1 ) {
    XNextEvent(display, (XEvent *)&event);
    switch ( event.type ) {
      case Expose:
        {
          XClearWindow(display, frame_window);
          // Upkeep of interface usefulness.
          Window returned_root, returned_parent;
          Window* top_level_windows;
          unsigned int nwin = 0;
          XQueryTree(
              display,
              XDefaultRootWindow(display),
              &returned_root,
              &returned_parent,
              &top_level_windows,
              &nwin);

          time(&rawtime);
          timeinfo = localtime(&rawtime);
          strftime(contents, 80, "%a %d %b, %T %p", timeinfo);

          sprintf(contents, "%s [%d]", contents, nwin);


          XWindowAttributes window_attributes;
          int font_direction, font_ascent, font_descent;
          XCharStruct text_structure;
          XTextExtents(fontinfo, contents, contents_length,
              &font_direction, &font_ascent, &font_descent,
              &text_structure);
          XGetWindowAttributes(display, frame_window, &window_attributes);
          text_x = (window_attributes.width - text_structure.width) + 5;
          text_y = (window_attributes.height -
              (text_structure.ascent+text_structure.descent))/2;
          XDrawString(display, frame_window, graphical_context,
              text_x, text_y, contents, contents_length);
          break;
        }
      default:
        break;
    }
  }
  return 0;
}
< p > 如果你们中有人想知道这个工具的目的是什么,我正在编写一个窗口管理器(实际上我已经非常进展了,比如你可以打开应用程序、移动和调整它们的大小),这是我需要的一个调试工具。存储库在这里


也许从现有的窗口管理器开始,研究其源代码会更容易一些... - Basile Starynkevitch
顺便说一句,编写 X11 的 WM 很难。学习 EWMH。为什么不尝试编写 Wayland 的代码呢? - Basile Starynkevitch
是的,我知道这很难。这就是为什么我正在做它。我现在已经转向使用Xlib绑定的Go语言了。我考虑过使用wayland,但我只是找不到任何好的现成代码或文档来支持这种事情。 - Alexis Dumas
1个回答

0

你需要一些事件循环,例如调用poll(2)并处理延迟。你还应该调用XFlushXSync(因为Xlib正在缓冲请求)。

你可以考虑发送一些Expose事件给自己....

而且你应该研究xclock的源代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接