[Window] Add thumbnail of windows as option.

This commit is contained in:
Dave Davenport 2019-10-17 21:19:19 +02:00
parent 8590a7ccf2
commit aeecf34c27
9 changed files with 163 additions and 73 deletions

View File

@ -159,4 +159,5 @@ Settings config = {
.matching_negate_char = '-',
.cache_dir = NULL,
.window_thumbnail = FALSE,
};

View File

@ -2,39 +2,39 @@
* rofi -dump-theme output.
**/
* {
selected-normal-foreground: var(lightbg);
foreground: rgba ( 0, 43, 54, 100 % );
normal-foreground: var(foreground);
alternate-normal-background: var(lightbg);
red: rgba ( 220, 50, 47, 100 % );
selected-urgent-foreground: var(background);
blue: rgba ( 38, 139, 210, 100 % );
selected-active-foreground: var(background);
lightfg: rgba ( 88, 104, 117, 100 % );
separatorcolor: var(foreground);
urgent-foreground: var(red);
alternate-urgent-background: var(lightbg);
active-foreground: var(blue);
lightbg: rgba ( 238, 232, 213, 100 % );
selected-active-foreground: var(background);
alternate-active-background: var(lightbg);
background: rgba ( 253, 246, 227, 100 % );
alternate-normal-foreground: var(foreground);
normal-background: var(background);
lightfg: rgba ( 88, 104, 117, 100 % );
selected-normal-background: var(lightfg);
border-color: var(foreground);
spacing: 2;
separatorcolor: var(foreground);
urgent-background: var(background);
selected-urgent-background: var(red);
alternate-urgent-foreground: var(red);
border-color: var(foreground);
normal-background: var(background);
background-color: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: var(blue);
active-background: var(background);
alternate-active-background: var(lightbg);
active-foreground: var(blue);
blue: rgba ( 38, 139, 210, 100 % );
urgent-background: var(background);
alternate-normal-foreground: var(foreground);
selected-active-background: var(blue);
background: rgba ( 253, 246, 227, 100 % );
selected-normal-foreground: var(lightbg);
active-background: var(background);
alternate-active-foreground: var(blue);
alternate-normal-background: var(lightbg);
foreground: rgba ( 0, 43, 54, 100 % );
selected-urgent-background: var(red);
selected-urgent-foreground: var(background);
normal-foreground: var(foreground);
alternate-urgent-foreground: var(red);
selected-normal-background: var(lightfg);
}
element {
border: 0;
spacing: 5px ;
padding: 1px ;
spacing: 5px ;
border: 0;
}
element normal.normal {
background-color: var(normal-background);
@ -82,40 +82,40 @@ element-icon {
text-color: inherit;
}
window {
padding: 5;
background-color: var(background);
border: 1;
padding: 5;
}
mainbox {
border: 0;
padding: 0;
border: 0;
}
message {
border: 2px dash 0px 0px ;
border-color: var(separatorcolor);
padding: 1px ;
border-color: var(separatorcolor);
border: 2px dash 0px 0px ;
}
textbox {
text-color: var(foreground);
}
listview {
fixed-height: 0;
border: 2px dash 0px 0px ;
padding: 2px 0px 0px ;
scrollbar: true;
border-color: var(separatorcolor);
spacing: 2px ;
scrollbar: true;
padding: 2px 0px 0px ;
fixed-height: 0;
border: 2px dash 0px 0px ;
}
scrollbar {
width: 4px ;
padding: 0;
handle-width: 8px ;
border: 0;
handle-color: var(normal-foreground);
handle-width: 8px ;
padding: 0;
}
sidebar {
border: 2px dash 0px 0px ;
border-color: var(separatorcolor);
border: 2px dash 0px 0px ;
}
button {
spacing: 0;
@ -126,9 +126,9 @@ button selected {
text-color: var(selected-normal-foreground);
}
inputbar {
padding: 1px ;
spacing: 0px ;
text-color: var(normal-foreground);
padding: 1px ;
children: [ prompt,textbox-prompt-colon,entry,case-indicator ];
}
case-indicator {
@ -144,8 +144,8 @@ prompt {
text-color: var(normal-foreground);
}
textbox-prompt-colon {
margin: 0px 0.3000em 0.0000em 0.0000em ;
expand: false;
str: ":";
margin: 0px 0.3000em 0.0000em 0.0000em ;
text-color: inherit;
}

View File

@ -2,39 +2,39 @@
* rofi -dump-theme output.
**/
* {
selected-normal-foreground: rgba ( 2, 20, 63, 100 % );
foreground: rgba ( 219, 223, 188, 100 % );
normal-foreground: var(foreground);
alternate-normal-background: rgba ( 0, 0, 0, 0 % );
red: rgba ( 220, 50, 47, 100 % );
selected-urgent-foreground: rgba ( 2, 20, 63, 100 % );
blue: rgba ( 38, 139, 210, 100 % );
selected-active-foreground: rgba ( 2, 20, 63, 100 % );
lightfg: rgba ( 88, 104, 117, 100 % );
separatorcolor: rgba ( 219, 223, 188, 100 % );
urgent-foreground: rgba ( 255, 129, 255, 100 % );
alternate-urgent-background: rgba ( 0, 0, 0, 0 % );
active-foreground: rgba ( 138, 196, 255, 100 % );
lightbg: rgba ( 238, 232, 213, 100 % );
selected-active-foreground: rgba ( 2, 20, 63, 100 % );
alternate-active-background: rgba ( 0, 0, 0, 0 % );
background: rgba ( 0, 0, 33, 87 % );
alternate-normal-foreground: var(foreground);
normal-background: rgba ( 0, 0, 0, 0 % );
lightfg: rgba ( 88, 104, 117, 100 % );
selected-normal-background: rgba ( 219, 223, 188, 100 % );
border-color: rgba ( 219, 223, 188, 100 % );
spacing: 2;
separatorcolor: rgba ( 219, 223, 188, 100 % );
urgent-background: rgba ( 0, 0, 0, 0 % );
selected-urgent-background: rgba ( 255, 129, 127, 100 % );
alternate-urgent-foreground: var(urgent-foreground);
border-color: rgba ( 219, 223, 188, 100 % );
normal-background: rgba ( 0, 0, 0, 0 % );
background-color: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: var(active-foreground);
active-background: rgba ( 0, 0, 0, 0 % );
alternate-active-background: rgba ( 0, 0, 0, 0 % );
active-foreground: rgba ( 138, 196, 255, 100 % );
blue: rgba ( 38, 139, 210, 100 % );
urgent-background: rgba ( 0, 0, 0, 0 % );
alternate-normal-foreground: var(foreground);
selected-active-background: rgba ( 138, 196, 255, 100 % );
background: rgba ( 0, 0, 33, 87 % );
selected-normal-foreground: rgba ( 2, 20, 63, 100 % );
active-background: rgba ( 0, 0, 0, 0 % );
alternate-active-foreground: var(active-foreground);
alternate-normal-background: rgba ( 0, 0, 0, 0 % );
foreground: rgba ( 219, 223, 188, 100 % );
selected-urgent-background: rgba ( 255, 129, 127, 100 % );
selected-urgent-foreground: rgba ( 2, 20, 63, 100 % );
normal-foreground: var(foreground);
alternate-urgent-foreground: var(urgent-foreground);
selected-normal-background: rgba ( 219, 223, 188, 100 % );
}
element {
border: 0;
spacing: 5px ;
padding: 1px ;
spacing: 5px ;
border: 0;
}
element normal.normal {
background-color: var(normal-background);
@ -82,40 +82,40 @@ element-icon {
text-color: inherit;
}
window {
padding: 5;
background-color: var(background);
border: 1;
padding: 5;
}
mainbox {
border: 0;
padding: 0;
border: 0;
}
message {
border: 2px 0px 0px ;
border-color: var(separatorcolor);
padding: 1px ;
border-color: var(separatorcolor);
border: 2px 0px 0px ;
}
textbox {
text-color: var(foreground);
}
listview {
fixed-height: 0;
border: 2px 0px 0px ;
padding: 2px 0px 0px ;
scrollbar: true;
border-color: var(separatorcolor);
spacing: 2px ;
scrollbar: true;
padding: 2px 0px 0px ;
fixed-height: 0;
border: 2px 0px 0px ;
}
scrollbar {
width: 4px ;
padding: 0;
handle-width: 8px ;
border: 0;
handle-color: var(normal-foreground);
handle-width: 8px ;
padding: 0;
}
sidebar {
border: 2px dash 0px 0px ;
border-color: var(separatorcolor);
border: 2px dash 0px 0px ;
}
button {
spacing: 0;
@ -126,9 +126,9 @@ button selected {
text-color: var(selected-normal-foreground);
}
inputbar {
padding: 1px ;
spacing: 0px ;
text-color: var(normal-foreground);
padding: 1px ;
children: [ prompt,textbox-prompt-colon,entry,case-indicator ];
}
case-indicator {
@ -144,9 +144,9 @@ prompt {
text-color: var(normal-foreground);
}
textbox-prompt-colon {
margin: 0px 0.3000em 0.0000em 0.0000em ;
expand: false;
str: ":";
margin: 0px 0.3000em 0.0000em 0.0000em ;
text-color: inherit;
}
mode-switcher {

View File

@ -126,6 +126,8 @@ rofi.scroll-method: 0
! rofi.matching-negate-char: -
! "Directory where history and temporary files are stored." Set from: Default
! rofi.cache-dir:
! "Show window thumbnail in window switcher if availalbe." Set from: Default
! rofi.window-thumbnail: false
! "Pidfile location" Set from: File
rofi.pid: /tmp/rofi.pid
! "Paste primary selection" Set from: File

View File

@ -189,6 +189,9 @@ typedef struct
/** Cache directory. */
char *cache_dir;
/** Window Thumbnails */
gboolean window_thumbnail;
} Settings;
/** Global Settings structure. */
extern Settings config;

View File

@ -181,4 +181,13 @@ typedef enum
*/
extern WindowManagerQuirk current_window_manager;
/**
* @param window the window the screenshot
* @param size Size of the thumbnail
*
* Creates a thumbnail of the window.
*
* @returns NULL if window was not found, or unmapped, otherwise returns a cairo_surface.
*/
cairo_surface_t *x11_helper_get_screenshot_surface_window ( xcb_window_t window, int size );
#endif

View File

@ -112,6 +112,7 @@ typedef struct
cairo_surface_t *icon;
gboolean icon_checked;
uint32_t icon_fetch_uid;
gboolean thumbnail_checked;
} client;
// window lists
@ -910,7 +911,11 @@ static cairo_surface_t *_get_icon ( const Mode *sw, unsigned int selected_line,
{
ModeModePrivateData *rmpd = mode_get_private_data ( sw );
client *c = window_client ( rmpd, rmpd->ids->array[selected_line] );
if ( c->icon_checked == FALSE ) {
if ( config.window_thumbnail && c->thumbnail_checked == FALSE ) {
c->icon = x11_helper_get_screenshot_surface_window ( c->window, size );
c->thumbnail_checked = TRUE;
}
if ( c->icon == NULL && c->icon_checked == FALSE ) {
c->icon = get_net_wm_icon ( rmpd->ids->array[selected_line], size );
c->icon_checked = TRUE;
}

View File

@ -99,6 +99,74 @@ static xcb_visualtype_t *root_visual = NULL;
xcb_atom_t netatoms[NUM_NETATOMS];
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
static xcb_visualtype_t * lookup_visual (xcb_screen_t *s, xcb_visualid_t visual)
{
xcb_depth_iterator_t d;
d = xcb_screen_allowed_depths_iterator (s);
for (; d.rem; xcb_depth_next (&d)) {
xcb_visualtype_iterator_t v = xcb_depth_visuals_iterator (d.data);
for (; v.rem; xcb_visualtype_next (&v)) {
if (v.data->visual_id == visual)
return v.data;
}
}
return 0;
}
cairo_surface_t *x11_helper_get_screenshot_surface_window ( xcb_window_t window, int size )
{
xcb_get_geometry_cookie_t cookie;
xcb_get_geometry_reply_t *reply;
cookie = xcb_get_geometry(xcb->connection, window);
reply = xcb_get_geometry_reply(xcb->connection, cookie, NULL);
if ( reply == NULL ) {
return NULL;
}
xcb_get_window_attributes_cookie_t attributesCookie = xcb_get_window_attributes (xcb->connection, window);
xcb_get_window_attributes_reply_t *attributes = xcb_get_window_attributes_reply (xcb->connection,
attributesCookie,
NULL );
if ( attributes == NULL || ( attributes->map_state != XCB_MAP_STATE_VIEWABLE ) ) {
free(reply);
if ( attributes ) free(attributes);
return NULL;
}
// Create a cairo surface for the window.
xcb_visualtype_t * vt = lookup_visual(xcb->screen, attributes->visual);
free ( attributes );
cairo_surface_t *t = cairo_xcb_surface_create ( xcb->connection, window, vt , reply->width, reply->height );
if ( cairo_surface_status ( t ) != CAIRO_STATUS_SUCCESS ) {
cairo_surface_destroy(t);
free(reply);
return NULL;
}
// Scale the image, as we don't want to keep large one around.
int max = MAX(reply->width, reply->height);
double scale = (double)size/ max;
cairo_surface_t *s2 = cairo_surface_create_similar_image ( t, CAIRO_FORMAT_ARGB32, reply->width*scale,reply->height*scale );
free ( reply );
if ( cairo_surface_status ( s2 ) != CAIRO_STATUS_SUCCESS ) {
cairo_surface_destroy ( t ) ;
return NULL;
}
// Paint it in.
cairo_t *d = cairo_create (s2);
cairo_scale ( d, scale, scale );
cairo_set_source_surface ( d, t, 0, 0 );
cairo_paint ( d);
cairo_destroy(d);
cairo_surface_destroy(t);
return s2;
}
/**
* Holds for each supported modifier the possible modifier mask.
* Check x11_mod_masks[MODIFIER]&mask != 0 to see if MODIFIER is activated.

View File

@ -223,6 +223,8 @@ static XrmOption xrmOptions[] = {
"Set the character used to negate the matching. ('\\0' to disable)", CONFIG_DEFAULT },
{ xrm_String, "cache-dir", { .str = &config.cache_dir }, NULL,
"Directory where history and temporary files are stored.", CONFIG_DEFAULT },
{ xrm_Boolean, "window-thumbnail", { .snum = &config.window_thumbnail }, NULL,
"Show window thumbnail in window switcher if availalbe.", CONFIG_DEFAULT },
};
/** Dynamic array of extra options */