1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

WIP: Port window stuff to xcb

Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
Quentin Glidic 2016-02-21 19:42:32 +01:00
parent 6bb1d4b1a2
commit 2ef950eab9
12 changed files with 192 additions and 167 deletions

View file

@ -87,7 +87,7 @@ GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11])
PKG_CHECK_MODULES([x11], [x11 x11-xcb]) PKG_CHECK_MODULES([x11], [x11 x11-xcb])
PKG_CHECK_MODULES([xinerama], [xinerama]) PKG_CHECK_MODULES([xinerama], [xinerama])
PKG_CHECK_MODULES([pango], [pango pangocairo]) PKG_CHECK_MODULES([pango], [pango pangocairo])
PKG_CHECK_MODULES([cairo], [cairo cairo-xlib]) PKG_CHECK_MODULES([cairo], [cairo cairo-xcb])
PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0]) PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0])

View file

@ -28,7 +28,7 @@ void i3_support_focus_window ( Window id );
* @returns TRUE when i3 is running, FALSE when not. * @returns TRUE when i3 is running, FALSE when not.
*/ */
int i3_support_initialize ( Display *display ); int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection );
/** /**
* Cleanup. * Cleanup.

View file

@ -142,7 +142,7 @@ void textbox_insert ( textbox *tb, int pos, char *str, int slen );
* before any of the textbox_ functions is called. * before any of the textbox_ functions is called.
* Clean with textbox_cleanup() * Clean with textbox_cleanup()
*/ */
void textbox_setup ( Display *display ); void textbox_setup ( void );
/** /**
* Cleanup the allocated colors and fonts by textbox_setup(). * Cleanup the allocated colors and fonts by textbox_setup().

View file

@ -90,7 +90,7 @@ void rofi_view_update ( RofiViewState *state );
* *
* Enables fake transparancy on this view. * Enables fake transparancy on this view.
*/ */
void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state ); void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state );
/** /**
* @param state The handle to the view * @param state The handle to the view

View file

@ -1,6 +1,7 @@
#ifndef X11_ROFI_HELPER_H #ifndef X11_ROFI_HELPER_H
#define X11_ROFI_HELPER_H #define X11_ROFI_HELPER_H
#include <cairo.h> #include <cairo.h>
#include <xcb/xcb.h>
#include "xkb.h" #include "xkb.h"
@ -27,7 +28,7 @@ int window_get_prop ( Display *display, Window w, Atom prop,
char* window_get_text_prop ( Display *display, Window w, Atom atom ); char* window_get_text_prop ( Display *display, Window w, Atom atom );
int window_get_atom_prop ( Display *display, Window w, Atom atom, Atom *list, int count ); int window_get_atom_prop ( Display *display, Window w, Atom atom, Atom *list, int count );
void window_set_atom_prop ( Display *display, Window w, Atom prop, Atom *atoms, int count ); void window_set_atom_prop ( Display *display, Window w, Atom atom, Atom *atoms, int count );
int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned long *list, int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned long *list,
int count ); int count );
@ -134,13 +135,16 @@ void x11_set_window_opacity ( Display *display, Window box, unsigned int opacity
*/ */
void x11_setup ( Display *display, xkb_stuff *xkb ); void x11_setup ( Display *display, xkb_stuff *xkb );
extern xcb_depth_t *depth;
extern xcb_visualtype_t *visual;
extern xcb_colormap_t map;
extern xcb_depth_t *root_depth;
extern xcb_visualtype_t *root_visual;
/** /**
* @param display Connection to the X server.
*
* This function tries to create a 32bit TrueColor colormap. * This function tries to create a 32bit TrueColor colormap.
* If this fails, it falls back to the default for the connected display. * If this fails, it falls back to the default for the connected display.
*/ */
void create_visual_and_colormap ( Display *display ); void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen );
typedef struct typedef struct
{ {
@ -153,11 +157,11 @@ typedef struct
* *
* Allocate a pixel value for an X named color * Allocate a pixel value for an X named color
*/ */
Color color_get ( Display *display, const char *const name, const char * const defn ); Color color_get ( const char *const name );
void color_background ( Display *display, cairo_t *d ); void color_background ( cairo_t *d );
void color_border ( Display *display, cairo_t *d ); void color_border ( cairo_t *d );
void color_separator ( Display *display, cairo_t *d ); void color_separator ( cairo_t *d );
void color_cache_reset ( void ); void color_cache_reset ( void );
void x11_helper_set_cairo_rgba ( cairo_t *d, Color col ); void x11_helper_set_cairo_rgba ( cairo_t *d, Color col );

View file

@ -74,6 +74,7 @@ typedef struct
long hint_flags; long hint_flags;
} client; } client;
// TODO // TODO
extern xcb_connection_t *xcb_connection;
extern Display *display; extern Display *display;
// window lists // window lists
typedef struct typedef struct
@ -387,7 +388,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd )
x11_cache_create (); x11_cache_create ();
// Check for i3 // Check for i3
pd->config_i3_mode = i3_support_initialize ( display ); pd->config_i3_mode = i3_support_initialize ( display, xcb_connection );
// Get the active window so we can highlight this. // Get the active window so we can highlight this.
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) ) if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) )

View file

@ -113,20 +113,21 @@ void i3_support_focus_window ( Window id )
close ( s ); close ( s );
} }
int i3_support_initialize ( Display *display ) int i3_support_initialize ( Display *display, xcb_connection_t *xcb_connection )
{ {
// If we where initialized, clean this first. // If we where initialized, clean this first.
i3_support_free_internals (); i3_support_free_internals ();
// Get atom for I3_SOCKET_PATH
Atom i3_sp_atom = XInternAtom ( display, "I3_SOCKET_PATH", False );
if ( i3_sp_atom != None ) { // Get atom for I3_SOCKET_PATH
xcb_intern_atom_cookie_t cookie = xcb_intern_atom ( xcb_connection, FALSE, strlen ( "I3_SOCKET_PATH" ), "I3_SOCKET_PATH" );
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply ( xcb_connection, cookie, NULL );
if ( reply != NULL ) {
// Get the default screen. // Get the default screen.
Screen *screen = DefaultScreenOfDisplay ( display ); Screen *screen = DefaultScreenOfDisplay ( display );
// Find the root window (each X has one.). // Find the root window (each X has one.).
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) ); Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
// Get the i3 path property. // Get the i3 path property.
i3_socket_path = window_get_text_prop ( display, root, i3_sp_atom ); i3_socket_path = window_get_text_prop ( display, root, reply->atom );
} }
// If we find it, go into i3 mode. // If we find it, go into i3 mode.
return ( i3_socket_path != NULL ) ? TRUE : FALSE; return ( i3_socket_path != NULL ) ? TRUE : FALSE;

View file

@ -139,8 +139,8 @@ static int setup ()
int pfd = create_pid_file ( pidfile ); int pfd = create_pid_file ( pidfile );
if ( pfd >= 0 ) { if ( pfd >= 0 ) {
// Request truecolor visual. // Request truecolor visual.
create_visual_and_colormap ( display ); x11_create_visual_and_colormap ( xcb_connection, xcb_screen );
textbox_setup ( display ); textbox_setup ();
} }
return pfd; return pfd;
} }

View file

@ -98,7 +98,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw )
// Cap length; // Cap length;
height = MIN ( bh - y + 1, ( height ) ); height = MIN ( bh - y + 1, ( height ) );
// Redraw base window // Redraw base window
color_separator ( display, draw ); color_separator ( draw );
cairo_rectangle ( draw, sb->widget.x + config.line_margin, sb->widget.y + y, sb->widget.w - config.line_margin, height ); cairo_rectangle ( draw, sb->widget.x + config.line_margin, sb->widget.y + y, sb->widget.w - config.line_margin, height );
cairo_fill ( draw ); cairo_fill ( draw );

View file

@ -621,11 +621,7 @@ int textbox_keypress ( textbox *tb, char *pad, int pad_len, unsigned int modstat
/*** /***
* Font setup. * Font setup.
*/ */
static void parse_color ( Display *display, char *bg, Color *col ) static void textbox_parse_string ( const char *str, RowColor *color )
{
*col = color_get ( display, bg, "white" );
}
static void textbox_parse_string ( Display *display, const char *str, RowColor *color )
{ {
if ( str == NULL ) { if ( str == NULL ) {
return; return;
@ -638,50 +634,50 @@ static void textbox_parse_string ( Display *display, const char *str, RowColor
switch ( index ) switch ( index )
{ {
case 0: case 0:
parse_color ( display, g_strstrip ( token ), &( color->bg ) ); color->bg = color_get ( g_strstrip ( token ) );
break; break;
case 1: case 1:
parse_color ( display, g_strstrip ( token ), &( color->fg ) ); color->fg = color_get ( g_strstrip ( token ) );
break; break;
case 2: case 2:
parse_color ( display, g_strstrip ( token ), &( color->bgalt ) ); color->bgalt = color_get ( g_strstrip ( token ) );
break; break;
case 3: case 3:
parse_color ( display, g_strstrip ( token ), &( color->hlbg ) ); color->hlbg = color_get ( g_strstrip ( token ) );
break; break;
case 4: case 4:
parse_color ( display, g_strstrip ( token ), &( color->hlfg ) ); color->hlfg = color_get ( g_strstrip ( token ) );
break; break;
} }
index++; index++;
} }
g_free ( cstr ); g_free ( cstr );
} }
void textbox_setup ( Display *display ) void textbox_setup ( void )
{ {
if ( config.color_enabled ) { if ( config.color_enabled ) {
textbox_parse_string ( display, config.color_normal, &( colors[NORMAL] ) ); textbox_parse_string ( config.color_normal, &( colors[NORMAL] ) );
textbox_parse_string ( display, config.color_urgent, &( colors[URGENT] ) ); textbox_parse_string ( config.color_urgent, &( colors[URGENT] ) );
textbox_parse_string ( display, config.color_active, &( colors[ACTIVE] ) ); textbox_parse_string ( config.color_active, &( colors[ACTIVE] ) );
} }
else { else {
parse_color ( display, config.menu_bg, &( colors[NORMAL].bg ) ); colors[NORMAL].bg = color_get ( config.menu_bg );
parse_color ( display, config.menu_fg, &( colors[NORMAL].fg ) ); colors[NORMAL].fg = color_get ( config.menu_fg );
parse_color ( display, config.menu_bg_alt, &( colors[NORMAL].bgalt ) ); colors[NORMAL].bgalt = color_get ( config.menu_bg_alt );
parse_color ( display, config.menu_hlfg, &( colors[NORMAL].hlfg ) ); colors[NORMAL].hlfg = color_get ( config.menu_hlfg );
parse_color ( display, config.menu_hlbg, &( colors[NORMAL].hlbg ) ); colors[NORMAL].hlbg = color_get ( config.menu_hlbg );
parse_color ( display, config.menu_bg_urgent, &( colors[URGENT].bg ) ); colors[URGENT].bg = color_get ( config.menu_bg_urgent );
parse_color ( display, config.menu_fg_urgent, &( colors[URGENT].fg ) ); colors[URGENT].fg = color_get ( config.menu_fg_urgent );
parse_color ( display, config.menu_bg_alt, &( colors[URGENT].bgalt ) ); colors[URGENT].bgalt = color_get ( config.menu_bg_alt );
parse_color ( display, config.menu_hlfg_urgent, &( colors[URGENT].hlfg ) ); colors[URGENT].hlfg = color_get ( config.menu_hlfg_urgent );
parse_color ( display, config.menu_hlbg_urgent, &( colors[URGENT].hlbg ) ); colors[URGENT].hlbg = color_get ( config.menu_hlbg_urgent );
parse_color ( display, config.menu_bg_active, &( colors[ACTIVE].bg ) ); colors[ACTIVE].bg = color_get ( config.menu_bg_active );
parse_color ( display, config.menu_fg_active, &( colors[ACTIVE].fg ) ); colors[ACTIVE].fg = color_get ( config.menu_fg_active );
parse_color ( display, config.menu_bg_alt, &( colors[ACTIVE].bgalt ) ); colors[ACTIVE].bgalt = color_get ( config.menu_bg_alt );
parse_color ( display, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) ); colors[ACTIVE].hlfg = color_get ( config.menu_hlfg_active );
parse_color ( display, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) ); colors[ACTIVE].hlbg = color_get ( config.menu_hlbg_active );
} }
} }

View file

@ -46,7 +46,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <cairo.h> #include <cairo.h>
#include <cairo-xlib.h> #include <cairo-xcb.h>
#define SN_API_NOT_YET_FROZEN #define SN_API_NOT_YET_FROZEN
#include <libsn/sn.h> #include <libsn/sn.h>
@ -68,17 +68,17 @@
// What todo with these. // What todo with these.
extern Display *display; extern Display *display;
extern xcb_connection_t *xcb_connection;
extern xcb_screen_t *xcb_screen;
extern SnLauncheeContext *sncontext; extern SnLauncheeContext *sncontext;
GThreadPool *tpool = NULL; GThreadPool *tpool = NULL;
RofiViewState *current_active_menu = NULL; RofiViewState *current_active_menu = NULL;
Window main_window = None; xcb_window_t main_window = XCB_WINDOW_NONE;
cairo_surface_t *surface = NULL; cairo_surface_t *surface = NULL;
cairo_surface_t *fake_bg = NULL; cairo_surface_t *fake_bg = NULL;
cairo_t *draw = NULL; cairo_t *draw = NULL;
Colormap map = None;
XVisualInfo vinfo;
static char * get_matching_state ( void ) static char * get_matching_state ( void )
{ {
@ -408,7 +408,7 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb
if ( state->w != xce->width || state->h != xce->height ) { if ( state->w != xce->width || state->h != xce->height ) {
state->w = xce->width; state->w = xce->width;
state->h = xce->height; state->h = xce->height;
cairo_xlib_surface_set_size ( surface, state->w, state->h ); cairo_xcb_surface_set_size ( surface, state->w, state->h );
rofi_view_resize ( state ); rofi_view_resize ( state );
} }
} }
@ -488,22 +488,31 @@ static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data )
g_mutex_unlock ( t->mutex ); g_mutex_unlock ( t->mutex );
} }
static Window __create_window ( Display *display, MenuFlags menu_flags ) static Window __create_window ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, MenuFlags menu_flags )
{ {
XSetWindowAttributes attr; uint32_t selmask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
attr.colormap = map; uint32_t selval[] =
attr.border_pixel = 0; { 0,
attr.background_pixel = 0; 0,
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_1_MOTION,map };
Window box = XCreateWindow ( display, DefaultRootWindow ( display ), 0, 0, 200, 100, 0, vinfo.depth, InputOutput, xcb_window_t box = xcb_generate_id ( xcb_connection );
vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr ); xcb_create_window ( xcb_connection,
XSelectInput ( depth->depth,
display,
box, box,
KeyReleaseMask | KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask | xcb_screen->root,
Button1MotionMask ); 0,
0,
200,
100,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
visual->visual_id,
selmask,
selval );
surface = cairo_xlib_surface_create ( display, box, vinfo.visual, 200, 100 ); surface = cairo_xcb_surface_create ( xcb_connection, box, visual, 200, 100 );
// Create a drawable. // Create a drawable.
draw = cairo_create ( surface ); draw = cairo_create ( surface );
g_assert ( draw != NULL ); g_assert ( draw != NULL );
@ -894,17 +903,17 @@ void rofi_view_update ( RofiViewState *state )
-(double) ( state->y - state->mon.y ) ); -(double) ( state->y - state->mon.y ) );
cairo_paint ( d ); cairo_paint ( d );
cairo_set_operator ( d, CAIRO_OPERATOR_OVER ); cairo_set_operator ( d, CAIRO_OPERATOR_OVER );
color_background ( display, d ); color_background ( d );
cairo_paint ( d ); cairo_paint ( d );
} }
} }
else { else {
// Paint the background. // Paint the background.
color_background ( display, d ); color_background ( d );
cairo_paint ( d ); cairo_paint ( d );
} }
TICK_N ( "Background" ); TICK_N ( "Background" );
color_border ( display, d ); color_border ( d );
if ( config.menu_bw > 0 ) { if ( config.menu_bw > 0 ) {
cairo_save ( d ); cairo_save ( d );
@ -935,7 +944,7 @@ void rofi_view_update ( RofiViewState *state )
if ( state->message_tb ) { if ( state->message_tb ) {
textbox_draw ( state->message_tb, d ); textbox_draw ( state->message_tb, d );
} }
color_separator ( display, d ); color_separator ( d );
if ( strcmp ( config.separator_style, "none" ) ) { if ( strcmp ( config.separator_style, "none" ) ) {
if ( strcmp ( config.separator_style, "dash" ) == 0 ) { if ( strcmp ( config.separator_style, "dash" ) == 0 ) {
@ -1243,16 +1252,14 @@ void rofi_view_finalize ( RofiViewState *state )
state->finalize ( state ); state->finalize ( state );
} }
} }
void rofi_view_setup_fake_transparency ( Display *display, RofiViewState *state ) void rofi_view_setup_fake_transparency ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen, RofiViewState *state )
{ {
if ( fake_bg == NULL ) { if ( fake_bg == NULL ) {
Window root = DefaultRootWindow ( display ); cairo_surface_t *s = cairo_xcb_surface_create ( xcb_connection,
int screen = DefaultScreen ( display ); xcb_screen->root,
cairo_surface_t *s = cairo_xlib_surface_create ( display, root_visual,
root, xcb_screen->width_in_pixels,
DefaultVisual ( display, screen ), xcb_screen->height_in_pixels );
DisplayWidth ( display, screen ),
DisplayHeight ( display, screen ) );
fake_bg = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, state->mon.w, state->mon.h ); fake_bg = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, state->mon.w, state->mon.h );
cairo_t *dr = cairo_create ( fake_bg ); cairo_t *dr = cairo_create ( fake_bg );
@ -1532,9 +1539,8 @@ RofiViewState *rofi_view_create ( Mode *sw,
} }
TICK_N ( "Grab keyboard" ); TICK_N ( "Grab keyboard" );
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
XWindowAttributes attr; if ( main_window == 0 ) {
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) { main_window = __create_window ( xcb_connection, xcb_screen, menu_flags );
main_window = __create_window ( display, menu_flags );
if ( sncontext != NULL ) { if ( sncontext != NULL ) {
sn_launchee_context_setup_window ( sncontext, main_window ); sn_launchee_context_setup_window ( sncontext, main_window );
} }
@ -1544,7 +1550,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
monitor_active ( display, &( state->mon ) ); monitor_active ( display, &( state->mon ) );
TICK_N ( "Get active monitor" ); TICK_N ( "Get active monitor" );
if ( config.fake_transparency ) { if ( config.fake_transparency ) {
rofi_view_setup_fake_transparency ( display, state ); rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state );
} }
// we need this at this point so we can get height. // we need this at this point so we can get height.
@ -1643,12 +1649,14 @@ RofiViewState *rofi_view_create ( Mode *sw,
( mode == state->sw ) ? HIGHLIGHT : NORMAL, mode_get_name ( mode ) ); ( mode == state->sw ) ? HIGHLIGHT : NORMAL, mode_get_name ( mode ) );
} }
} }
uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
uint32_t vals[] = { state->x, state->y, state->w, state->h };
// Display it. // Display it.
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h ); xcb_configure_window ( xcb_connection, main_window, mask, vals );
cairo_xlib_surface_set_size ( surface, state->w, state->h ); cairo_xcb_surface_set_size ( surface, state->w, state->h );
XMapRaised ( display, main_window ); xcb_map_window ( xcb_connection, main_window );
XFlush ( display ); xcb_flush ( xcb_connection );
// if grabbing keyboard failed, fall through // if grabbing keyboard failed, fall through
state->selected = 0; state->selected = 0;
@ -1695,12 +1703,11 @@ void rofi_view_error_dialog ( const char *msg, int markup )
// Get active monitor size. // Get active monitor size.
monitor_active ( display, &( state->mon ) ); monitor_active ( display, &( state->mon ) );
if ( config.fake_transparency ) { if ( config.fake_transparency ) {
rofi_view_setup_fake_transparency ( display, state ); rofi_view_setup_fake_transparency ( xcb_connection, xcb_screen, state );
} }
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker // main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
XWindowAttributes attr; if ( main_window == 0 ) {
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) { main_window = __create_window ( xcb_connection, xcb_screen, MENU_NORMAL );
main_window = __create_window ( display, MENU_NORMAL );
} }
rofi_view_calculate_window_and_element_width ( state ); rofi_view_calculate_window_and_element_width ( state );
@ -1715,11 +1722,14 @@ void rofi_view_error_dialog ( const char *msg, int markup )
state->h = state->line_height + ( state->border ) * 2; state->h = state->line_height + ( state->border ) * 2;
// Move the window to the correct x,y position. // Move the window to the correct x,y position.
uint16_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
uint32_t vals[] = { state->x, state->y, state->w, state->h };
xcb_configure_window ( xcb_connection, main_window, mask, vals );
calculate_window_position ( state ); calculate_window_position ( state );
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h ); cairo_xcb_surface_set_size ( surface, state->w, state->h );
cairo_xlib_surface_set_size ( surface, state->w, state->h );
// Display it. // Display it.
XMapRaised ( display, main_window ); xcb_map_window ( xcb_connection, main_window );
if ( sncontext != NULL ) { if ( sncontext != NULL ) {
sn_launchee_context_complete ( sncontext ); sn_launchee_context_complete ( sncontext );
@ -1741,15 +1751,14 @@ void rofi_view_cleanup ()
cairo_surface_destroy ( surface ); cairo_surface_destroy ( surface );
surface = NULL; surface = NULL;
} }
if ( main_window != None ) { if ( main_window != XCB_WINDOW_NONE ) {
XUnmapWindow ( display, main_window ); xcb_unmap_window ( xcb_connection, main_window );
XDestroyWindow ( display, main_window ); xcb_destroy_window ( xcb_connection, main_window );
main_window = None; main_window = XCB_WINDOW_NONE;
} }
if ( map != XCB_COLORMAP_NONE ) {
if ( map != None ) { xcb_free_colormap ( xcb_connection, map );
XFreeColormap ( display, map ); map = XCB_COLORMAP_NONE;
map = None;
} }
} }
void rofi_view_workers_initialize ( void ) void rofi_view_workers_initialize ( void )

View file

@ -34,6 +34,7 @@
#include <glib.h> #include <glib.h>
#include <cairo.h> #include <cairo.h>
#include <xcb/xcb.h>
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -68,12 +69,15 @@ enum
NUM_X11MOD NUM_X11MOD
}; };
xcb_depth_t *depth = NULL;
xcb_visualtype_t *visual = NULL;
xcb_colormap_t map = XCB_COLORMAP_NONE;
xcb_depth_t *root_depth = NULL;
xcb_visualtype_t *root_visual = NULL;
Atom netatoms[NUM_NETATOMS]; Atom netatoms[NUM_NETATOMS];
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) }; const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
static unsigned int x11_mod_masks[NUM_X11MOD]; static unsigned int x11_mod_masks[NUM_X11MOD];
extern Colormap map;
// retrieve a property of any type from a window // retrieve a property of any type from a window
int window_get_prop ( Display *display, Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes ) int window_get_prop ( Display *display, Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes )
{ {
@ -523,71 +527,81 @@ void x11_setup ( Display *display, xkb_stuff *xkb )
x11_create_frequently_used_atoms ( display ); x11_create_frequently_used_atoms ( display );
} }
extern XVisualInfo vinfo; void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen )
int truecolor = FALSE;
void create_visual_and_colormap ( Display *display )
{ {
int screen = DefaultScreen ( display ); xcb_depth_iterator_t depth_iter;
// Try to create TrueColor map for ( depth_iter = xcb_screen_allowed_depths_iterator ( xcb_screen ); depth_iter.rem; xcb_depth_next ( &depth_iter ) ) {
if ( XMatchVisualInfo ( display, screen, 32, TrueColor, &vinfo ) ) { xcb_depth_t *d = depth_iter.data;
// Visual found, lets try to create map.
map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone ); xcb_visualtype_iterator_t visual_iter;
truecolor = TRUE; for ( visual_iter = xcb_depth_visuals_iterator ( d ); visual_iter.rem; xcb_visualtype_next ( &visual_iter ) ) {
xcb_visualtype_t *v = visual_iter.data;
if ( ( d->depth == 32 ) && ( v->_class == XCB_VISUAL_CLASS_TRUE_COLOR ) ) {
depth = d;
visual = v;
} }
// Failed to create map. if ( xcb_screen->root_visual == v->visual_id ) {
// Use the defaults then. root_depth = d;
if ( map == None ) { root_visual = v;
truecolor = FALSE; }
// Two fields we use. }
vinfo.visual = DefaultVisual ( display, screen ); }
vinfo.depth = DefaultDepth ( display, screen ); if ( visual != NULL ) {
map = DefaultColormap ( display, screen ); xcb_void_cookie_t c;
xcb_generic_error_t *e;
map = xcb_generate_id ( xcb_connection );
c = xcb_create_colormap_checked ( xcb_connection, XCB_COLORMAP_ALLOC_NONE, map, xcb_screen->root, visual->visual_id );
e = xcb_request_check ( xcb_connection, c );
if ( e ) {
depth = NULL;
visual = NULL;
free ( e );
} }
} }
Color color_get ( Display *display, const char *const name, const char * const defn ) if ( visual == NULL ) {
depth = root_depth;
visual = root_visual;
map = xcb_screen->default_colormap;
}
}
Color color_get ( const char *const name )
{ {
char *copy = g_strdup ( name ); char *copy = g_strdup ( name );
char *cname = g_strstrip ( copy ); char *cname = g_strstrip ( copy );
XColor color = { 0, 0, 0, 0, 0, 0 };
XColor def; union
{
struct
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
};
uint32_t pixel;
} color = {
.r = 0xff,
.g = 0xff,
.b = 0xff,
.a = 0xff,
};
// Special format. // Special format.
if ( strncmp ( cname, "argb:", 5 ) == 0 ) { if ( strncmp ( cname, "argb:", 5 ) == 0 ) {
color.pixel = strtoul ( &cname[5], NULL, 16 ); color.pixel = strtoul ( &cname[5], NULL, 16 );
color.red = ( ( color.pixel & 0x00FF0000 ) >> 16 ) * 256;
color.green = ( ( color.pixel & 0x0000FF00 ) >> 8 ) * 256;
color.blue = ( ( color.pixel & 0x000000FF ) ) * 256;
if ( !truecolor ) {
// This will drop alpha part.
Status st = XAllocColor ( display, map, &color );
if ( st == None ) {
fprintf ( stderr, "Failed to parse color: '%s'\n", cname );
st = XAllocNamedColor ( display, map, defn, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to allocate fallback color\n" );
exit ( EXIT_FAILURE );
}
}
}
}
else {
Status st = XAllocNamedColor ( display, map, cname, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to parse color: '%s'\n", cname );
st = XAllocNamedColor ( display, map, defn, &color, &def );
if ( st == None ) {
fprintf ( stderr, "Failed to allocate fallback color\n" );
exit ( EXIT_FAILURE );
}
} }
else if ( strncmp ( cname, "#", 1 ) == 0 ) {
color.pixel = strtoul ( &cname[1], NULL, 16 );
color.a = 0xff;
} }
g_free ( copy ); g_free ( copy );
Color ret = { Color ret = {
.red = color.red / 65535.0, .red = color.r / 255.0,
.green = color.green / 65535.0, .green = color.g / 255.0,
.blue = color.blue / 65535.0, .blue = color.b / 255.0,
.alpha = ( ( color.pixel & 0xFF000000 ) >> 24 ) / 255.0, .alpha = color.a / 255.0,
}; };
return ret; return ret;
} }
@ -619,16 +633,16 @@ void color_cache_reset ( void )
color_cache[BORDER].set = FALSE; color_cache[BORDER].set = FALSE;
color_cache[SEPARATOR].set = FALSE; color_cache[SEPARATOR].set = FALSE;
} }
void color_background ( Display *display, cairo_t *d ) void color_background ( cairo_t *d )
{ {
if ( !color_cache[BACKGROUND].set ) { if ( !color_cache[BACKGROUND].set ) {
if ( !config.color_enabled ) { if ( !config.color_enabled ) {
color_cache[BACKGROUND].color = color_get ( display, config.menu_bg, "black" ); color_cache[BACKGROUND].color = color_get ( config.menu_bg );
} }
else { else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 ); gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL ) { if ( vals != NULL && vals[0] != NULL ) {
color_cache[BACKGROUND].color = color_get ( display, vals[0], "black" ); color_cache[BACKGROUND].color = color_get ( vals[0] );
} }
g_strfreev ( vals ); g_strfreev ( vals );
} }
@ -638,16 +652,16 @@ void color_background ( Display *display, cairo_t *d )
x11_helper_set_cairo_rgba ( d, color_cache[BACKGROUND].color ); x11_helper_set_cairo_rgba ( d, color_cache[BACKGROUND].color );
} }
void color_border ( Display *display, cairo_t *d ) void color_border ( cairo_t *d )
{ {
if ( !color_cache[BORDER].set ) { if ( !color_cache[BORDER].set ) {
if ( !config.color_enabled ) { if ( !config.color_enabled ) {
color_cache[BORDER].color = color_get ( display, config.menu_bc, "white" ); color_cache[BORDER].color = color_get ( config.menu_bc );
} }
else { else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 ); gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) { if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) {
color_cache[BORDER].color = color_get ( display, vals[1], "white" ); color_cache[BORDER].color = color_get ( vals[1] );
} }
g_strfreev ( vals ); g_strfreev ( vals );
} }
@ -656,19 +670,19 @@ void color_border ( Display *display, cairo_t *d )
x11_helper_set_cairo_rgba ( d, color_cache[BORDER].color ); x11_helper_set_cairo_rgba ( d, color_cache[BORDER].color );
} }
void color_separator ( Display *display, cairo_t *d ) void color_separator ( cairo_t *d )
{ {
if ( !color_cache[SEPARATOR].set ) { if ( !color_cache[SEPARATOR].set ) {
if ( !config.color_enabled ) { if ( !config.color_enabled ) {
color_cache[SEPARATOR].color = color_get ( display, config.menu_bc, "white" ); color_cache[SEPARATOR].color = color_get ( config.menu_bc );
} }
else { else {
gchar **vals = g_strsplit ( config.color_window, ",", 3 ); gchar **vals = g_strsplit ( config.color_window, ",", 3 );
if ( vals != NULL && vals[0] != NULL && vals[1] != NULL && vals[2] != NULL ) { if ( vals != NULL && vals[0] != NULL && vals[1] != NULL && vals[2] != NULL ) {
color_cache[SEPARATOR].color = color_get ( display, vals[2], "white" ); color_cache[SEPARATOR].color = color_get ( vals[2] );
} }
else if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) { else if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) {
color_cache[SEPARATOR].color = color_get ( display, vals[1], "white" ); color_cache[SEPARATOR].color = color_get ( vals[1] );
} }
g_strfreev ( vals ); g_strfreev ( vals );
} }