LINUX.ORG.RU

XCB{,+Cairo }

 , , , ,


1

1

создал окно типа панели.. рисуем срествами (xcb || cairo)

ни с одним, ни с другим не могу решить проблему перерисовки..(после перекрытия окном на «панели» остается «след» от окна)

смотрел исходники панелей и оконных менеджеров.. когда нашел мелкий исходник минипанели, выяснил, что cairo используется в связке с pango, но последний мне не нужен.. текст можно и средствами xcb вывести..

кстати, dwm на xlib не косячит с перерисовкой, dwm на xcb косячит также, как и моя «панель»..

или предложите другое решение.. надоело безрезультатно топтаться на одном месте..

ЗЫ:: конечное приложение будет собрано по кусочкам нескольких..

★★

Тебе надо рисовать при помощи cairo в обработчике expose event. Ты же на чистом XCB пишешь, правильно? UPD. Да, и тебе понадобится написать, наверное, event compression (почитай про это, так делается в тулкитах), потому что expose буду посылаться на любое изменение области рисования. На пиксель окно сдвинется - expose вызовет перерисовку. Тебе надо делать перерисовку не так часто.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

правильно, но expose тут даже ни при чем, ибо я в двм убирал все упоминания о перерисовке панели, таких косяков, как с xcb, замечено не было..

ЗЫ:: и еще, на xlib добавлял вторую панель - косяков ноль.. но на c xlib проблема с потоками

TODD ★★
() автор топика
Ответ на: комментарий от Zubok

делать надо часто, хочу вывесить на панель часы с выводом секунд, поэтому хочу создать поток с перерисовкой панели с интервалом в 1 сек.. потому что в бездействии ничего не перерисовывается, даже в чистом двм(проверено)..

ЗЫ:: на панели будут не только часы.. остальные функции по получению данных в разработке

TODD ★★
() автор топика
Последнее исправление: TODD (всего исправлений: 1)
Ответ на: комментарий от TODD

правильно, но expose тут даже ни при чем,

Почему ты решил, что не при чем? Вот это вот о чем говорит?

после перекрытия окном на «панели» остается «след» от окна

Как у тебя перерисовка панели организована? У тебя обрабатывается Expose? Если да, то что в нем?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

expose в моем случае лишний..

поэтому хочу создать поток с перерисовкой панели с интервалом в 1 сек.. потому что в бездействии ничего не перерисовывается

я вырезаю то, чем я абсолютно не пользуюсь или то, что не нужно..

если обновление в 1 сек, то обработка expose будет перегружать поток событий, а т.к. отрисовка будет тяжелой, он будет тормозить все приложение..

TODD ★★
() автор топика
Последнее исправление: TODD (всего исправлений: 1)
Ответ на: комментарий от TODD

expose в моем случае лишний..

Я не понимаю. Честно. Ты шарашишь по таймеру каждую секунду перерисовку всей панели? Дикость как она есть. Перерисовывать надо только то, что меняется. Если ничего не меняется, то и не надо перерисовывать. Если что-то должно измениться (часы), то надо перерисовать часы в тот момент, когда изменилось время.

А вот проходящие поверх окна - это случайные факторы! Когда по окну (твоей панели) проходит другое окно, то твой X-клиент от X-сервера получает сообщения о том, что твое окно надо перерисовать, так как оно портится. Вернее, он тебе сообщает регион, который надо перерисовать, а делать ли это, решает твоя программа. Если backingstore не работает, то при прохождении окна у тебя постоянно будут сыпаться эти сообщения.

Если ты перерисовываешь текст, то это не значит, что у тебя перерисовывается все окно. След от окна не перерисуется. Надо все или испорченный кусочек перезалить цветом и перерисовать участок. Или лови сообщения expose с count=0 и перерисовывай всю панель. Но это не очень эстетично.

Получение сообщений Expose разрешаются маской.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

awesome панель справа не заполнена, но как видишь, графики и т.п.

cairo на линиях и тексте, при увеличении ширины все остальное также расширяется.. ио увеличивается/уменьшается в высоту в зависимости от кол-ва s{d,r}*

так что для часов 1 сек, проц и ио 1.5, память 2, будет еще инет

мне удобно по хоткею глянуть инфу, тут же сообразить на сколько поднялась/упала та или иная величина(удобно при I/O ж/д)

TODD ★★
() автор топика
Ответ на: комментарий от Zubok

Перерисовывать надо только то, что меняется.

предлагаешь сократить время для графиков? ио диска 0 на протяжении 10 минут, ничего не рисовать? тогда какой смысл от графиков? в случае прогресс-баров и текста это приемлемо.. но от них мало информативности..

TODD ★★
() автор топика
Ответ на: комментарий от TODD

Это все не имеет отношения к порче окна проходящим по нему другим окном. Так как ты не используешь тулкит и программируешь на низком уровне, то все манипуляции с перерисовкой испорченных регионов надо делать самому. Для того, чобы узнать, что кто-то прошелся по твоему окну, есть событие Expose (есть еще GraphicExpose). Окно открылось поперек твоей панели и исчезло — cлед остается. В событии Expose тебе придет регион, который испортился и который надо перерисовать. Так делают все тулкиты и все приложения, которые используют напряму xcb или xlib.

Разница только в том, что одни перерисовывают оптимальнее других: умеют только часть перерисовать, а не все окно, делают перерисовку не на каждое Expose, а сжимают очередь этих событий.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 3)
Ответ на: комментарий от TODD

если обновление в 1 сек, то обработка expose будет перегружать поток событий, а т.к. отрисовка будет тяжелой, он будет тормозить все приложение..

Не будет. Когда приходит Expose, надо создать pixmap и отрисовать при помощи cairo в него, а не прямо в окно, а потом помощи xcb_copy_area из этого pixmap в испорченное окно вставить кусочек. Вообще, держать теневой pixmap является неплохой идеей.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

не используешь тулкит и программируешь на низком уровне

;) имел дело с WinApi на оффтопике.. чем легче приложение - тем лучше..

одни перерисовывают оптимальнее других: умеют только часть перерисовать, а не все окно, делают перерисовку не на каждое Expose, а сжимают очередь этих событий.

интересно.. не встречал таких, ибо на руках исходники оконных менеджеров, а там схема одна.. (некоторые форки)

________________________

Конечно не имеет отношения, это пример того, что будет..

________________________

единственное чего я не могу понять.. при нагрузке на жд отклик осома на хоткеи возрастает в десятки раз..

как этого избежать? данные берутся из {proc,sys}..

TODD ★★
() автор топика
Последнее исправление: TODD (всего исправлений: 1)
Ответ на: комментарий от TODD

странно, что автор, переписавший dwm на xcb, не учел этого.. отсюдова и косяки изначально идут..

Ну-ка, гляну исходнички. Вот это: https://github.com/julian-goldsmith/dwm-xcb/blob/master/dwm.c ?

Вроде есть обработчик с перерисовкой (drawbar)

int expose(xcb_generic_event_t *e) {
    Monitor *m;
    xcb_expose_event_t *ev = (xcb_expose_event_t*)e;
    if(ev->count == 0 && (m = wintomon(ev->window)))
    drawbar(m);
    return 0;
}
Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от TODD

интересно.. не встречал таких, ибо на руках исходники оконных менеджеров, а там схема одна.. (некоторые форки)

А они, наверное, имеют теневой pixmap, куда прорисовывают сначала, а когда получают expose, то как заплатку из теневого pixmap вставляют в окно. Например, awesome:

drawin_refresh_pixmap_partial(drawin_t *drawin,
                              int16_t x, int16_t y,
                              uint16_t w, uint16_t h)
{
    if (!drawin->drawable || !drawin->drawable->pixmap || !drawin->drawable->refreshed)
        return;

    /* Make cairo do all pending drawing */
    cairo_surface_flush(drawin->drawable->surface);
    xcb_copy_area(globalconf.connection, drawin->drawable->pixmap,
                  drawin->window, globalconf.gc, x, y, x, y,
                  w, h);
}

Про сжатие вот, например раздел 7.9.3: http://lesstif.sourceforge.net/doc/super-ux/g1ae03e/part1/chap7.html#pg9

Оно необязательно. Для простых окон, как это замечено, можно просто все перерисовать. В очереди стоят события Expose, в которых об изменении каждого кусочка сообщается. Если простое кошко, небольшое окошко, то эффективнее все перерисовать.

Вот еще Qt (на нужной строчке стоит в самом верху):

https://qt.gitorious.org/qt/thiago-intels-qtbase/source/3acd4b546ded7523f65d6...

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

странно, что автор, переписавший dwm на xcb, не учел этого.. отсюдова и косяки изначально идут..

Вроде есть обработчик с перерисовкой (drawbar)

Если все равно остаются следы, то, скорее всего, процедура drawbar() не все перерисовывает. Возможно, что она фон не перерисовывает, поэтому остаются следы. Тогда это просто баг в перерисовке.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

возможно какое-то сообщение перекрывает expose

при начале перемещения панель отрисовывается, потому что окно «переполучает» фокус, где как-раз прописана drawbars.. пока окно перемещается, на панели ничего не отрисовывается, ровным счетом ничего.. и expose не обрабатывается..

я особо не сравнивал версии.. у меня с xcb 5,8,2, с xlib 6.0.. возможно где-то чего-то недостает.. я пытался 6,0 переписать под xcb, но бросил из-за недостачи функций в 5,8,2-xcb, в частности getstate (емнип)..

TODD ★★
() автор топика
Ответ на: комментарий от TODD

А в чем задача изначально? Вот, что я не понял. Что-то свое пишешь или исправляешь чужую версию? Или что?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

среднее между своим и чужим.. грубо говоря, пилю под себя, но не на уровне конфигов.. правда с моими познаниями времени уйдет немало при его нехватке..

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

изначальная идея, но ушел в сторону.. потихоньку буду паять с исходников на досуге.. придется попотеть, когда начнется работа с атомами: не все гладко там, как казалось..

ЗЫ:: unix-way вряд ли будет..

TODD ★★
() автор топика
Ответ на: комментарий от Zubok

оказалось эффективнее в плане багов подобно этому:

    cairo_surface_flush(drawin->drawable->surface);
    xcb_copy_area(globalconf.connection, drawin->drawable->pixmap,
                  drawin->window, globalconf.gc, x, y, x, y,
                  w, h);

если сразу рисовать на окно, то при множестве expose ивентов начинаются артефакты в виде горизонтальных полос(надеюсь понятно)..

задумался над реализацией граф-боксов..

________________

на досуге думал про awesome

все управление и внешний вид написано на lua как «конфиг».. а бинарник в купе с внутренними функциями «исполняет» этот «конфиг», или все куда хуже, чем я думаю?

TODD ★★
() автор топика
Ответ на: комментарий от TODD

если сразу рисовать на окно, то при множестве expose ивентов начинаются артефакты в виде горизонтальных полос(надеюсь понятно)..

Классический double buffering (код из awesome): http://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_...

все управление и внешний вид написано на lua как «конфиг».. а бинарник в купе с внутренними функциями «исполняет» этот «конфиг», или все куда хуже, чем я думаю?

Все вроде так: очень много функций по управлению окнами выведено сразу на уровень lua, что позволяет скриптовать это хозяйство. Подобные идеи уже были давно. Например, Sawfish, FVWM.

Disclamer: я не пользователь awesome.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

я не пользователь awesome

я этого не утверждал.. ;)

double buffering, хмм.. у коньков вроде подобное было. емнип, коньки тоже с lua связаны..

TODD ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.