def test_title_position_remains(hlwm, x11): active_color = (212, 189, 140) normal_color = (221, 198, 104) hlwm.attr.theme.active.title_color = RawImage.rgb2string(active_color) hlwm.attr.theme.normal.title_color = RawImage.rgb2string(normal_color) hlwm.attr.settings.tabbed_max = True hlwm.attr.theme.title_height = 10 hlwm.attr.theme.outer_width = 3 hlwm.attr.tags.focus.tiling.focused_frame.algorithm = 'max' handle1, win1 = x11.create_client() x11.set_window_title(handle1, 'client 1') handle2, win2 = x11.create_client() x11.set_window_title(handle1, 'client 2') for align in ['left', 'center', 'right']: hlwm.attr.theme.title_align = align hlwm.call(['jumpto', win1]) focus1 = x11.decoration_screenshot(handle1) hlwm.call(['jumpto', win2]) focus2 = x11.decoration_screenshot(handle2) assert focus1.height == focus2.height assert focus1.width == focus2.width titlebar_height = 10 for x, y in itertools.product(range(0, focus1.width), range(0, titlebar_height)): assert (focus1.pixel(x, y) == active_color) == (focus2.pixel(x, y) == normal_color), \ f'mismatch at pixel ({x}, {y})' assert (focus1.pixel(x, y) == normal_color) == (focus2.pixel(x, y) == active_color), \ f'mismatch at pixel ({x}, {y})'
def test_frame_holes_for_pseudotiled_client(hlwm, x11, frame_bg_transparent): bgcol = (0xef, 0xcd, 0x32) hlwm.attr.settings.frame_bg_active_color = RawImage.rgb2string(bgcol) hlwm.attr.settings.frame_bg_transparent = frame_bg_transparent hlwm.attr.settings.frame_transparent_width = 8 [frame_win] = x11.get_hlwm_frames() geo = frame_win.get_geometry() w = geo.width h = geo.height # create a pseudotiled client that is very wide but not very high: winhandle, winid = x11.create_client(geometry=(0, 0, w + 10, h // 3 - 10)) hlwm.attr.clients[winid].pseudotile = 'on' img = x11.screenshot(frame_win) assert (img.width, img.height) == (w, h) # the frame is visible on the top and bottom img.pixel(0, 0) == bgcol img.pixel(0, h - 1) == bgcol img.pixel(w // 2, 0) == bgcol img.pixel(w // 2, h - 1) == bgcol # but the frame is not visible on the left and right black = (0, 0, 0) img.pixel(0, h // 2) == black img.pixel(w - 1, h // 2) == black img.pixel(w // 2, h // 2) == black
def test_decoration_tab_title_update(hlwm, x11): text_color = (212, 189, 140) hlwm.attr.theme.title_color = RawImage.rgb2string(text_color) hlwm.attr.theme.title_height = 20 hlwm.call(['set_layout', 'max']) # split twice to make tab area smaller and screenshots faster :-) hlwm.call(['split', 'bottom']) hlwm.call(['split', 'bottom']) count = 5 win_handles = [x11.create_client()[0] for _ in range(0, count)] # empty all window titles: for wh in win_handles: x11.set_window_title(wh, '') # focus handle 0: hlwm.call(['jumpto', x11.winid_str(win_handles[0])]) # take a screenshot, it should not contain the text_color: assert x11.decoration_screenshot( win_handles[0]).color_count(text_color) == 0 # change the title of an unfocused window: x11.set_window_title(win_handles[2], 'SOMETHING') # this change should now be visible in the tab bar, at least 5 pixels # should have this color now: assert x11.decoration_screenshot( win_handles[0]).color_count(text_color) > 5
def test_title_does_not_exceed_width(hlwm, x11, font, ellipsis): font_color = (255, 0, 0) # a color available everywhere bw = 30 hlwm.attr.theme.color = 'black' hlwm.attr.theme.title_color = RawImage.rgb2string(font_color) hlwm.attr.theme.title_height = 14 hlwm.attr.theme.padding_top = 0 hlwm.attr.theme.padding_left = 0 hlwm.attr.theme.padding_right = 0 hlwm.attr.theme.border_width = bw hlwm.attr.theme.title_font = font hlwm.attr.settings.ellipsis = ellipsis handle, winid = x11.create_client() # set a title that is too wide to be displayed in its entirety: w = hlwm.attr.clients[winid].decoration_geometry().width if font[0] != '-': three_bytes_per_glyph = 'ヘールブストルフト' assert len(three_bytes_per_glyph.encode( 'UTF-8')) == 3 * len(three_bytes_per_glyph) # for xft fonts, also test utf8 window titles utf8titles = [ w * '♥', (w // 3) * 'äüöß', (w // len(three_bytes_per_glyph)) * three_bytes_per_glyph, ] else: # for plain X fonts, it does not seem to work in tox/pytest # (but strangely, it works in a manual Xephyr session) utf8titles = [] for title in [w * '=', w * '|'] + utf8titles: img = screenshot_with_title(x11, handle, title) # verify that the title does not span too wide to the # left or to the right: # find leftmost non-black pixel: leftmost_font_x = None for x in range(0, w): for y in range(0, 14): # only verify top `title_height`-many pixels if img.pixel(x, y) != (0, 0, 0): leftmost_font_x = x break if leftmost_font_x is not None: break # find rightmost non-black pixel: rightmost_font_x = None for x in range(w - 1, 0, -1): for y in range(0, 14): # only verify top `title_height`-many pixels if img.pixel(x, y) != (0, 0, 0): rightmost_font_x = x break if rightmost_font_x is not None: break assert leftmost_font_x >= bw assert rightmost_font_x < bw + hlwm.attr.clients[ winid].content_geometry().width
def test_window_border_outer(hlwm, x11): color = (239, 2, 190) bw = 6 # border width outer_color = (48, 225, 26) outer_bw = 3 hlwm.attr.theme.color = RawImage.rgb2string(color) hlwm.attr.theme.border_width = bw hlwm.attr.theme.outer_color = RawImage.rgb2string(outer_color) hlwm.attr.theme.outer_width = outer_bw handle, _ = x11.create_client() img = x11.decoration_screenshot(handle) # check the upper left corner for x in range(0, bw): for y in range(0, bw): threshold = outer_bw expected_color = outer_color if x < threshold or y < threshold else color assert img.pixel(x, y) == expected_color
def test_window_border_inner(hlwm, x11): color = (239, 2, 190) bw = 5 # border width inner_color = (48, 225, 26) inner_bw = 2 hlwm.attr.theme.color = RawImage.rgb2string(color) hlwm.attr.theme.border_width = bw hlwm.attr.theme.inner_color = RawImage.rgb2string(inner_color) hlwm.attr.theme.inner_width = inner_bw handle, _ = x11.create_client() img = x11.decoration_screenshot(handle) # we check the inner border color in the upper left corner for x in range(0, bw): for y in range(0, bw): threshold = bw - inner_bw expected_color = inner_color if x >= threshold and y >= threshold else color assert img.pixel(x, y) == expected_color
def test_window_border_plain(hlwm, x11): color = (0x9f, 0xbc, 0x12) bw = 5 # border width handle, _ = x11.create_client() hlwm.attr.theme.color = RawImage.rgb2string(color) hlwm.attr.theme.border_width = bw img = x11.decoration_screenshot(handle) assert img.pixel(0, 0) == color expected_count = 2 * bw * img.width # horizontal border line expected_count += 2 * bw * img.height # vertical border expected_count -= 4 * bw * bw # we counted each twice assert img.color_count(color) == expected_count
def test_decoration_tab_urgent(hlwm, x11, running_clients, running_clients_num): active_color = (200, 23, 0) # something unique normal_color = (23, 200, 0) # something unique urgent_color = (17, 2, 189) # something unique hlwm.attr.theme.active.color = RawImage.rgb2string(active_color) hlwm.attr.theme.active.title_color = RawImage.rgb2string(active_color) hlwm.attr.theme.normal.color = RawImage.rgb2string(normal_color) hlwm.attr.theme.normal.title_color = RawImage.rgb2string(normal_color) hlwm.attr.theme.urgent.color = RawImage.rgb2string(urgent_color) hlwm.attr.theme.urgent.title_color = RawImage.rgb2string(urgent_color) hlwm.attr.theme.title_height = 20 hlwm.call(['load', '(clients max:0 {})'.format(' '.join(running_clients))]) # split twice to make tab area smaller and screenshots faster :-) hlwm.call(['split', 'bottom']) hlwm.call(['split', 'bottom']) winhandle = x11.window(running_clients[0]) img = x11.decoration_screenshot(winhandle) color_count = img.color_count_dict() assert urgent_color not in color_count # make one of the unfocused tabs urgent x11.make_window_urgent(x11.window(running_clients[2])) img = x11.decoration_screenshot(winhandle) new_color_count = img.color_count_dict() assert urgent_color in new_color_count # there is one 'normal' and one 'urgent' tab, so the colors should # appear similarly often: assert new_color_count[urgent_color] == new_color_count[normal_color] assert new_color_count[normal_color] == color_count[normal_color] / 2
def test_decoration_title_align(hlwm, x11, client_count): """test the title_align attribute, by computing the 'average' position of the title """ text_color = (212, 189, 140) hlwm.attr.theme.title_color = RawImage.rgb2string(text_color) hlwm.attr.settings.tabbed_max = True hlwm.attr.theme.title_height = 10 win_handle, winid = x11.create_client() hlwm.attr.tags.focus.tiling.focused_frame.algorithm = 'max' while hlwm.attr.tags.focus.client_count() < client_count: x11.create_client() assert hlwm.attr.clients.focus.winid() == winid x11.set_window_title(win_handle, '-') # compute the 'average' title position align_to_title_pos = {} for align in ['left', 'right', 'center']: hlwm.attr.theme.title_align = align img = x11.decoration_screenshot(win_handle) point_sum = Point(0, 0) point_count = 0 for x, y in itertools.product(range(0, img.width), range(0, img.height)): if img.pixel(x, y) == text_color: point_sum.x += x point_sum.y += y point_count += 1 # compute the average point: align_to_title_pos[align] = point_sum // point_count # all titles should be on the same height: assert align_to_title_pos['left'].y == align_to_title_pos['center'].y assert align_to_title_pos['center'].y == align_to_title_pos['right'].y # the x coordinate should be different by at least this: # the width of the decoration, divided by the number of tabs # and divided by roughly 3 :-) x_diff = hlwm.attr.clients.focus.decoration_geometry( ).width / client_count / 3 assert align_to_title_pos['left'].x + x_diff < align_to_title_pos[ 'center'].x assert align_to_title_pos['center'].x + x_diff < align_to_title_pos[ 'right'].x
def test_title_different_letters_are_drawn(hlwm, x11, font): """changing letters changes the image""" font_color = (255, 0, 0) # a color available everywhere hlwm.attr.theme.color = 'black' hlwm.attr.theme.title_color = RawImage.rgb2string(font_color) hlwm.attr.theme.title_height = 14 hlwm.attr.theme.padding_top = 4 hlwm.attr.theme.title_font = font handle, _ = x11.create_client() # put some characters in the title that take only few pixels count1 = screenshot_with_title(x11, handle, ',.b').color_count(font_color) # alter characters to others taking more pixels count2 = screenshot_with_title(x11, handle, ';:B').color_count(font_color) # then the number of pixels should have increased assert count1 < count2
def test_title_every_letter_is_drawn(hlwm, x11, font): """the number of letters has some effect""" font_color = (255, 0, 0) # a color available everywhere hlwm.attr.theme.color = 'black' hlwm.attr.theme.title_color = RawImage.rgb2string(font_color) hlwm.attr.theme.title_height = 14 hlwm.attr.theme.padding_top = 4 hlwm.attr.theme.title_font = font handle, _ = x11.create_client() # set the window title to some word count1 = screenshot_with_title(x11, handle, 'test').color_count(font_color) # duplicate the word in the title count2 = screenshot_with_title(x11, handle, 'test test').color_count(font_color) # then the number of pixels of the font_color should have doubled: assert count1 != 0 assert count1 * 2 == count2
def test_title_ellipsis_is_used(hlwm, x11, font): font_color = (255, 0, 0) # a color available everywhere bw = 30 hlwm.attr.theme.color = 'black' hlwm.attr.theme.title_color = RawImage.rgb2string(font_color) hlwm.attr.theme.title_height = 14 hlwm.attr.theme.border_width = bw hlwm.attr.theme.title_font = font hlwm.attr.settings.ellipsis = 'abc' handle, winid = x11.create_client() assert screenshot_with_title(x11, handle, ' ').color_count(font_color) == 0 # set a title that is too wide to be displayed in its entirety: w = hlwm.attr.clients[winid].decoration_geometry().width count1 = screenshot_with_title(x11, handle, w * ' ').color_count(font_color) assert count1 > 0 hlwm.attr.settings.ellipsis = 'abcabc' count2 = screenshot_with_title(x11, handle, w * ' ').color_count(font_color) assert count2 > 0 assert count2 == count1 * 2
def test_decoration_tab_colors(hlwm, x11, method, running_clients, running_clients_num): active_color = (200, 23, 0) # something unique normal_color = (23, 200, 0) # something unique hlwm.attr.theme.active.color = RawImage.rgb2string(active_color) hlwm.attr.theme.active.title_color = RawImage.rgb2string(active_color) if method == 'tab_*-attributes': hlwm.attr.theme.active.tab_color = RawImage.rgb2string(normal_color) hlwm.attr.theme.active.tab_title_color = RawImage.rgb2string( normal_color) hlwm.attr.theme.active.tab_outer_color = RawImage.rgb2string( normal_color) hlwm.attr.theme.active.tab_outer_width = 1 if method == 'other scheme': hlwm.attr.theme.normal.color = RawImage.rgb2string(normal_color) hlwm.attr.theme.normal.title_color = RawImage.rgb2string(normal_color) hlwm.attr.theme.title_height = 20 hlwm.call(['set_layout', 'max']) # split twice to make tab area smaller and screenshots faster :-) hlwm.call(['split', 'bottom']) hlwm.call(['split', 'bottom']) winhandle = x11.window(hlwm.attr.clients.focus.winid()) img = x11.decoration_screenshot(winhandle) color_count = img.color_count_dict() # we have three tabs, and one of them should have the active color: assert color_count[active_color] * (running_clients_num - 1) == color_count[normal_color] # if we disable tabs, then the 'normal_color' should disappear: hlwm.attr.settings.tabbed_max = False winhandle = x11.window(hlwm.attr.clients.focus.winid()) img = x11.decoration_screenshot(winhandle) new_color_count = img.color_count_dict() assert normal_color not in new_color_count assert new_color_count[ active_color] == running_clients_num * color_count[active_color]