2015-06-13 3 views
3

Итак, у меня есть приложение на C++, которое использует XLib. В нем я получаю доступ к дате и времени с помощью библиотеки ctime, а в событии Expose создаю строку из нее и помещаю ее в окно с центром. Моя проблема заключается в том, что время обновляется только при изменении размера, поэтому, например, секунды не меняются, если я не буду постоянно изменять размер окна. Вот код:Приложение XLib не перерисовывается, если не изменено.

#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; 
} 

В случае, если любой из вас задаются вопросом, с какой целью это для, я пишу оконный менеджер (я на самом деле получил очень далеко, как вы можете открыть приложения, перемещать и изменить их размер), и это инструмент, который мне нужен для отладки. Repo here

+0

Возможно, исходя из существующего WM и изучение его исходный код может быть проще ... –

+0

Кстати, писать WM для X11 сложно. Исследование EWMH. Почему бы вам не попробовать что-то сделать для Wayland? –

+0

Да, я знаю, что это сложно. Вот почему я это делаю. Я перешел, чтобы перейти сейчас, используя привязки Xlib. Я рассматривал использование wayland, но я просто не могу найти хороший код или документацию для такого рода вещей, которые уже существуют. –

ответ

0

Вам понадобится цикл событий, например. вызывая poll(2) и обрабатывая задержки. Вы также должны позвонить XFlush или XSync (поскольку Xlib является буферизацией).

Вы могли бы рассмотреть вопрос о направлении себя некоторые Expose событие ....

И вы должны изучить исходный код xclock