summaryrefslogtreecommitdiff
path: root/i3lock.c
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2011-04-02 19:49:38 +0200
committerMichael Stapelberg <michael@stapelberg.de>2011-04-02 19:49:38 +0200
commite03e93fd1bb6f347b13d42796c1f0dada4ca8bb5 (patch)
treeea4fe16a784b838f2ae3c9486411a1b9af0430bd /i3lock.c
parente7201e2df53e740e364d6d0992a1c6e329909e06 (diff)
optimization: render to pixmap which is used as background for the window
Before this commit, the background color (white by default) was visible for about 100ms until the image was drawn. This flickering is now eliminated. Also, we don’t need to handle Expose-events anymore, as X11 will use the window’s background pixmap automatically.
Diffstat (limited to 'i3lock.c')
-rw-r--r--i3lock.c79
1 files changed, 30 insertions, 49 deletions
diff --git a/i3lock.c b/i3lock.c
index 27144cb..a32d5b5 100644
--- a/i3lock.c
+++ b/i3lock.c
@@ -48,7 +48,6 @@ static bool beep = false;
#ifndef NOLIBCAIRO
static cairo_surface_t *img = NULL;
-static cairo_t *ctx = NULL;
static bool tile = false;
#endif
@@ -72,31 +71,6 @@ static void input_done() {
}
/*
- * Called when we should draw the image (if any).
- *
- */
-static void handle_expose_event() {
-#ifndef NOLIBCAIRO
- if (!ctx)
- return;
-
- if (tile) {
- /* create a pattern and fill a rectangle as big as the screen */
- cairo_pattern_t *pattern;
- pattern = cairo_pattern_create_for_surface(img);
- cairo_set_source(ctx, pattern);
- cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
- cairo_rectangle(ctx, 0, 0, scr->width_in_pixels, scr->height_in_pixels);
- cairo_fill(ctx);
- } else {
- /* otherwise, just paint the image */
- cairo_paint(ctx);
- }
-#endif
- xcb_flush(conn);
-}
-
-/*
* Called when the user releases a key. We need to leave the Mode_switch
* state when the user releases the Mode_switch key.
*
@@ -388,36 +362,48 @@ int main(int argc, char *argv[]) {
scr = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
vistype = get_root_visual_type(scr);
- /* open the fullscreen window and flush immediately afterwards so that X11
- * can generate an expose event while we load the PNG file (so that we are
- * ready to handle the expose event immediately afterwards) */
- win = open_fullscreen_window(conn, scr, color);
-
- cursor = create_cursor(conn, scr, win, curs_choice);
-
- grab_pointer_and_keyboard(conn, scr, cursor);
-
- symbols = xcb_key_symbols_alloc(conn);
- modeswitchmask = get_mod_mask(conn, symbols, XK_Mode_switch);
- numlockmask = get_mod_mask(conn, symbols, XK_Num_Lock);
+ /* Pixmap on which the image is rendered to (if any) */
+ xcb_pixmap_t bg_pixmap = XCB_NONE;
#ifndef NOLIBCAIRO
- if (image_path)
+ if (image_path) {
+ bg_pixmap = create_bg_pixmap(conn, scr, color);
+ /* Create a pixmap to render on, fill it with the background color */
img = cairo_image_surface_create_from_png(image_path);
+ }
if (img) {
/* Initialize cairo */
cairo_surface_t *output;
- output = cairo_xcb_surface_create(conn, win, vistype,
+ output = cairo_xcb_surface_create(conn, bg_pixmap, vistype,
scr->width_in_pixels, scr->height_in_pixels);
- ctx = cairo_create(output);
- if (!tile)
+ cairo_t *ctx = cairo_create(output);
+ if (!tile) {
cairo_set_source_surface(ctx, img, 0, 0);
-
- handle_expose_event();
+ cairo_paint(ctx);
+ } else {
+ /* create a pattern and fill a rectangle as big as the screen */
+ cairo_pattern_t *pattern;
+ pattern = cairo_pattern_create_for_surface(img);
+ cairo_set_source(ctx, pattern);
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+ cairo_rectangle(ctx, 0, 0, scr->width_in_pixels, scr->height_in_pixels);
+ cairo_fill(ctx);
+ }
}
#endif
+ /* open the fullscreen window, already with the correct pixmap in place */
+ win = open_fullscreen_window(conn, scr, color, bg_pixmap);
+
+ cursor = create_cursor(conn, scr, win, curs_choice);
+
+ grab_pointer_and_keyboard(conn, scr, cursor);
+
+ symbols = xcb_key_symbols_alloc(conn);
+ modeswitchmask = get_mod_mask(conn, symbols, XK_Mode_switch);
+ numlockmask = get_mod_mask(conn, symbols, XK_Num_Lock);
+
if (dpms)
dpms_turn_off_screen(conn);
@@ -428,11 +414,6 @@ int main(int argc, char *argv[]) {
/* Strip off the highest bit (set if the event is generated) */
int type = (event->response_type & 0x7F);
- if (type == XCB_EXPOSE) {
- handle_expose_event();
- continue;
- }
-
if (type == XCB_KEY_PRESS) {
handle_key_press((xcb_key_press_event_t*)event);
continue;