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:
parent
6bb1d4b1a2
commit
2ef950eab9
12 changed files with 192 additions and 167 deletions
|
@ -87,7 +87,7 @@ GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11])
|
|||
PKG_CHECK_MODULES([x11], [x11 x11-xcb])
|
||||
PKG_CHECK_MODULES([xinerama], [xinerama])
|
||||
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])
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ void i3_support_focus_window ( Window id );
|
|||
* @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.
|
||||
|
|
|
@ -142,7 +142,7 @@ void textbox_insert ( textbox *tb, int pos, char *str, int slen );
|
|||
* before any of the textbox_ functions is called.
|
||||
* Clean with textbox_cleanup()
|
||||
*/
|
||||
void textbox_setup ( Display *display );
|
||||
void textbox_setup ( void );
|
||||
|
||||
/**
|
||||
* Cleanup the allocated colors and fonts by textbox_setup().
|
||||
|
|
|
@ -90,7 +90,7 @@ void rofi_view_update ( RofiViewState *state );
|
|||
*
|
||||
* 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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef X11_ROFI_HELPER_H
|
||||
#define X11_ROFI_HELPER_H
|
||||
#include <cairo.h>
|
||||
#include <xcb/xcb.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 );
|
||||
|
||||
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 count );
|
||||
|
||||
|
@ -65,7 +66,7 @@ int window_get_cardinal_prop ( Display *display, Window w, Atom atom, unsigned l
|
|||
enum { EWMH_ATOMS ( ATOM_ENUM ), NUM_NETATOMS };
|
||||
|
||||
extern const char *netatom_names[];
|
||||
extern Atom netatoms[NUM_NETATOMS];
|
||||
extern Atom netatoms[NUM_NETATOMS];
|
||||
typedef struct
|
||||
{
|
||||
int x, y, w, h;
|
||||
|
@ -134,13 +135,16 @@ void x11_set_window_opacity ( Display *display, Window box, unsigned int opacity
|
|||
*/
|
||||
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.
|
||||
* 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
|
||||
{
|
||||
|
@ -153,11 +157,11 @@ typedef struct
|
|||
*
|
||||
* 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_border ( Display *display, cairo_t *d );
|
||||
void color_separator ( Display *display, cairo_t *d );
|
||||
void color_background ( cairo_t *d );
|
||||
void color_border ( cairo_t *d );
|
||||
void color_separator ( cairo_t *d );
|
||||
void color_cache_reset ( void );
|
||||
|
||||
void x11_helper_set_cairo_rgba ( cairo_t *d, Color col );
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct
|
|||
long hint_flags;
|
||||
} client;
|
||||
// TODO
|
||||
extern xcb_connection_t *xcb_connection;
|
||||
extern Display *display;
|
||||
// window lists
|
||||
typedef struct
|
||||
|
@ -387,7 +388,7 @@ static void _window_mode_load_data ( Mode *sw, unsigned int cd )
|
|||
|
||||
x11_cache_create ();
|
||||
// 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.
|
||||
if ( !( window_get_prop ( display, root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &curr_win_id, sizeof ( Window ) )
|
||||
|
|
|
@ -113,20 +113,21 @@ void i3_support_focus_window ( Window id )
|
|||
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.
|
||||
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.
|
||||
Screen *screen = DefaultScreenOfDisplay ( display );
|
||||
// Find the root window (each X has one.).
|
||||
Window root = RootWindow ( display, XScreenNumberOfScreen ( screen ) );
|
||||
// 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.
|
||||
return ( i3_socket_path != NULL ) ? TRUE : FALSE;
|
||||
|
|
|
@ -139,8 +139,8 @@ static int setup ()
|
|||
int pfd = create_pid_file ( pidfile );
|
||||
if ( pfd >= 0 ) {
|
||||
// Request truecolor visual.
|
||||
create_visual_and_colormap ( display );
|
||||
textbox_setup ( display );
|
||||
x11_create_visual_and_colormap ( xcb_connection, xcb_screen );
|
||||
textbox_setup ();
|
||||
}
|
||||
return pfd;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ void scrollbar_draw ( scrollbar *sb, cairo_t *draw )
|
|||
// Cap length;
|
||||
height = MIN ( bh - y + 1, ( height ) );
|
||||
// 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_fill ( draw );
|
||||
|
|
|
@ -621,11 +621,7 @@ int textbox_keypress ( textbox *tb, char *pad, int pad_len, unsigned int modstat
|
|||
/***
|
||||
* Font setup.
|
||||
*/
|
||||
static void parse_color ( Display *display, char *bg, Color *col )
|
||||
{
|
||||
*col = color_get ( display, bg, "white" );
|
||||
}
|
||||
static void textbox_parse_string ( Display *display, const char *str, RowColor *color )
|
||||
static void textbox_parse_string ( const char *str, RowColor *color )
|
||||
{
|
||||
if ( str == NULL ) {
|
||||
return;
|
||||
|
@ -638,50 +634,50 @@ static void textbox_parse_string ( Display *display, const char *str, RowColor
|
|||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
parse_color ( display, g_strstrip ( token ), &( color->bg ) );
|
||||
color->bg = color_get ( g_strstrip ( token ) );
|
||||
break;
|
||||
case 1:
|
||||
parse_color ( display, g_strstrip ( token ), &( color->fg ) );
|
||||
color->fg = color_get ( g_strstrip ( token ) );
|
||||
break;
|
||||
case 2:
|
||||
parse_color ( display, g_strstrip ( token ), &( color->bgalt ) );
|
||||
color->bgalt = color_get ( g_strstrip ( token ) );
|
||||
break;
|
||||
case 3:
|
||||
parse_color ( display, g_strstrip ( token ), &( color->hlbg ) );
|
||||
color->hlbg = color_get ( g_strstrip ( token ) );
|
||||
break;
|
||||
case 4:
|
||||
parse_color ( display, g_strstrip ( token ), &( color->hlfg ) );
|
||||
color->hlfg = color_get ( g_strstrip ( token ) );
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
g_free ( cstr );
|
||||
}
|
||||
void textbox_setup ( Display *display )
|
||||
void textbox_setup ( void )
|
||||
{
|
||||
if ( config.color_enabled ) {
|
||||
textbox_parse_string ( display, config.color_normal, &( colors[NORMAL] ) );
|
||||
textbox_parse_string ( display, config.color_urgent, &( colors[URGENT] ) );
|
||||
textbox_parse_string ( display, config.color_active, &( colors[ACTIVE] ) );
|
||||
textbox_parse_string ( config.color_normal, &( colors[NORMAL] ) );
|
||||
textbox_parse_string ( config.color_urgent, &( colors[URGENT] ) );
|
||||
textbox_parse_string ( config.color_active, &( colors[ACTIVE] ) );
|
||||
}
|
||||
else {
|
||||
parse_color ( display, config.menu_bg, &( colors[NORMAL].bg ) );
|
||||
parse_color ( display, config.menu_fg, &( colors[NORMAL].fg ) );
|
||||
parse_color ( display, config.menu_bg_alt, &( colors[NORMAL].bgalt ) );
|
||||
parse_color ( display, config.menu_hlfg, &( colors[NORMAL].hlfg ) );
|
||||
parse_color ( display, config.menu_hlbg, &( colors[NORMAL].hlbg ) );
|
||||
colors[NORMAL].bg = color_get ( config.menu_bg );
|
||||
colors[NORMAL].fg = color_get ( config.menu_fg );
|
||||
colors[NORMAL].bgalt = color_get ( config.menu_bg_alt );
|
||||
colors[NORMAL].hlfg = color_get ( config.menu_hlfg );
|
||||
colors[NORMAL].hlbg = color_get ( config.menu_hlbg );
|
||||
|
||||
parse_color ( display, config.menu_bg_urgent, &( colors[URGENT].bg ) );
|
||||
parse_color ( display, config.menu_fg_urgent, &( colors[URGENT].fg ) );
|
||||
parse_color ( display, config.menu_bg_alt, &( colors[URGENT].bgalt ) );
|
||||
parse_color ( display, config.menu_hlfg_urgent, &( colors[URGENT].hlfg ) );
|
||||
parse_color ( display, config.menu_hlbg_urgent, &( colors[URGENT].hlbg ) );
|
||||
colors[URGENT].bg = color_get ( config.menu_bg_urgent );
|
||||
colors[URGENT].fg = color_get ( config.menu_fg_urgent );
|
||||
colors[URGENT].bgalt = color_get ( config.menu_bg_alt );
|
||||
colors[URGENT].hlfg = color_get ( config.menu_hlfg_urgent );
|
||||
colors[URGENT].hlbg = color_get ( config.menu_hlbg_urgent );
|
||||
|
||||
parse_color ( display, config.menu_bg_active, &( colors[ACTIVE].bg ) );
|
||||
parse_color ( display, config.menu_fg_active, &( colors[ACTIVE].fg ) );
|
||||
parse_color ( display, config.menu_bg_alt, &( colors[ACTIVE].bgalt ) );
|
||||
parse_color ( display, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) );
|
||||
parse_color ( display, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) );
|
||||
colors[ACTIVE].bg = color_get ( config.menu_bg_active );
|
||||
colors[ACTIVE].fg = color_get ( config.menu_fg_active );
|
||||
colors[ACTIVE].bgalt = color_get ( config.menu_bg_alt );
|
||||
colors[ACTIVE].hlfg = color_get ( config.menu_hlfg_active );
|
||||
colors[ACTIVE].hlbg = color_get ( config.menu_hlbg_active );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
115
source/view.c
115
source/view.c
|
@ -46,7 +46,7 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <cairo-xlib.h>
|
||||
#include <cairo-xcb.h>
|
||||
|
||||
#define SN_API_NOT_YET_FROZEN
|
||||
#include <libsn/sn.h>
|
||||
|
@ -68,17 +68,17 @@
|
|||
|
||||
// What todo with these.
|
||||
extern Display *display;
|
||||
extern xcb_connection_t *xcb_connection;
|
||||
extern xcb_screen_t *xcb_screen;
|
||||
extern SnLauncheeContext *sncontext;
|
||||
|
||||
GThreadPool *tpool = 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 *fake_bg = NULL;
|
||||
cairo_t *draw = NULL;
|
||||
Colormap map = None;
|
||||
XVisualInfo vinfo;
|
||||
|
||||
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 ) {
|
||||
state->w = xce->width;
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
@ -488,22 +488,31 @@ static void check_is_ascii ( thread_state *t, G_GNUC_UNUSED gpointer user_data )
|
|||
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;
|
||||
attr.colormap = map;
|
||||
attr.border_pixel = 0;
|
||||
attr.background_pixel = 0;
|
||||
uint32_t selmask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
|
||||
uint32_t selval[] =
|
||||
{ 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,
|
||||
vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr );
|
||||
XSelectInput (
|
||||
display,
|
||||
box,
|
||||
KeyReleaseMask | KeyPressMask | ExposureMask | ButtonPressMask | StructureNotifyMask | FocusChangeMask |
|
||||
Button1MotionMask );
|
||||
xcb_window_t box = xcb_generate_id ( xcb_connection );
|
||||
xcb_create_window ( xcb_connection,
|
||||
depth->depth,
|
||||
box,
|
||||
xcb_screen->root,
|
||||
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.
|
||||
draw = cairo_create ( surface );
|
||||
g_assert ( draw != NULL );
|
||||
|
@ -894,17 +903,17 @@ void rofi_view_update ( RofiViewState *state )
|
|||
-(double) ( state->y - state->mon.y ) );
|
||||
cairo_paint ( d );
|
||||
cairo_set_operator ( d, CAIRO_OPERATOR_OVER );
|
||||
color_background ( display, d );
|
||||
color_background ( d );
|
||||
cairo_paint ( d );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Paint the background.
|
||||
color_background ( display, d );
|
||||
color_background ( d );
|
||||
cairo_paint ( d );
|
||||
}
|
||||
TICK_N ( "Background" );
|
||||
color_border ( display, d );
|
||||
color_border ( d );
|
||||
|
||||
if ( config.menu_bw > 0 ) {
|
||||
cairo_save ( d );
|
||||
|
@ -935,7 +944,7 @@ void rofi_view_update ( RofiViewState *state )
|
|||
if ( state->message_tb ) {
|
||||
textbox_draw ( state->message_tb, d );
|
||||
}
|
||||
color_separator ( display, d );
|
||||
color_separator ( d );
|
||||
|
||||
if ( strcmp ( config.separator_style, "none" ) ) {
|
||||
if ( strcmp ( config.separator_style, "dash" ) == 0 ) {
|
||||
|
@ -1243,16 +1252,14 @@ void rofi_view_finalize ( RofiViewState *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 ) {
|
||||
Window root = DefaultRootWindow ( display );
|
||||
int screen = DefaultScreen ( display );
|
||||
cairo_surface_t *s = cairo_xlib_surface_create ( display,
|
||||
root,
|
||||
DefaultVisual ( display, screen ),
|
||||
DisplayWidth ( display, screen ),
|
||||
DisplayHeight ( display, screen ) );
|
||||
cairo_surface_t *s = cairo_xcb_surface_create ( xcb_connection,
|
||||
xcb_screen->root,
|
||||
root_visual,
|
||||
xcb_screen->width_in_pixels,
|
||||
xcb_screen->height_in_pixels );
|
||||
|
||||
fake_bg = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, state->mon.w, state->mon.h );
|
||||
cairo_t *dr = cairo_create ( fake_bg );
|
||||
|
@ -1532,9 +1539,8 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
}
|
||||
TICK_N ( "Grab keyboard" );
|
||||
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
|
||||
XWindowAttributes attr;
|
||||
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) {
|
||||
main_window = __create_window ( display, menu_flags );
|
||||
if ( main_window == 0 ) {
|
||||
main_window = __create_window ( xcb_connection, xcb_screen, menu_flags );
|
||||
if ( sncontext != NULL ) {
|
||||
sn_launchee_context_setup_window ( sncontext, main_window );
|
||||
}
|
||||
|
@ -1544,7 +1550,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
monitor_active ( display, &( state->mon ) );
|
||||
TICK_N ( "Get active monitor" );
|
||||
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.
|
||||
|
@ -1643,12 +1649,14 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
( 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.
|
||||
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h );
|
||||
cairo_xlib_surface_set_size ( surface, state->w, state->h );
|
||||
XMapRaised ( display, main_window );
|
||||
XFlush ( display );
|
||||
xcb_configure_window ( xcb_connection, main_window, mask, vals );
|
||||
cairo_xcb_surface_set_size ( surface, state->w, state->h );
|
||||
xcb_map_window ( xcb_connection, main_window );
|
||||
xcb_flush ( xcb_connection );
|
||||
|
||||
// if grabbing keyboard failed, fall through
|
||||
state->selected = 0;
|
||||
|
@ -1695,12 +1703,11 @@ void rofi_view_error_dialog ( const char *msg, int markup )
|
|||
// Get active monitor size.
|
||||
monitor_active ( display, &( state->mon ) );
|
||||
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
|
||||
XWindowAttributes attr;
|
||||
if ( main_window == None || XGetWindowAttributes ( display, main_window, &attr ) == 0 ) {
|
||||
main_window = __create_window ( display, MENU_NORMAL );
|
||||
if ( main_window == 0 ) {
|
||||
main_window = __create_window ( xcb_connection, xcb_screen, MENU_NORMAL );
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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 );
|
||||
XMoveResizeWindow ( display, main_window, state->x, state->y, state->w, state->h );
|
||||
cairo_xlib_surface_set_size ( surface, state->w, state->h );
|
||||
cairo_xcb_surface_set_size ( surface, state->w, state->h );
|
||||
// Display it.
|
||||
XMapRaised ( display, main_window );
|
||||
xcb_map_window ( xcb_connection, main_window );
|
||||
|
||||
if ( sncontext != NULL ) {
|
||||
sn_launchee_context_complete ( sncontext );
|
||||
|
@ -1741,15 +1751,14 @@ void rofi_view_cleanup ()
|
|||
cairo_surface_destroy ( surface );
|
||||
surface = NULL;
|
||||
}
|
||||
if ( main_window != None ) {
|
||||
XUnmapWindow ( display, main_window );
|
||||
XDestroyWindow ( display, main_window );
|
||||
main_window = None;
|
||||
if ( main_window != XCB_WINDOW_NONE ) {
|
||||
xcb_unmap_window ( xcb_connection, main_window );
|
||||
xcb_destroy_window ( xcb_connection, main_window );
|
||||
main_window = XCB_WINDOW_NONE;
|
||||
}
|
||||
|
||||
if ( map != None ) {
|
||||
XFreeColormap ( display, map );
|
||||
map = None;
|
||||
if ( map != XCB_COLORMAP_NONE ) {
|
||||
xcb_free_colormap ( xcb_connection, map );
|
||||
map = XCB_COLORMAP_NONE;
|
||||
}
|
||||
}
|
||||
void rofi_view_workers_initialize ( void )
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <glib.h>
|
||||
#include <cairo.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -68,12 +69,15 @@ enum
|
|||
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];
|
||||
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
||||
static unsigned int x11_mod_masks[NUM_X11MOD];
|
||||
|
||||
extern Colormap map;
|
||||
|
||||
// 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 )
|
||||
{
|
||||
|
@ -523,71 +527,81 @@ void x11_setup ( Display *display, xkb_stuff *xkb )
|
|||
x11_create_frequently_used_atoms ( display );
|
||||
}
|
||||
|
||||
extern XVisualInfo vinfo;
|
||||
int truecolor = FALSE;
|
||||
void create_visual_and_colormap ( Display *display )
|
||||
void x11_create_visual_and_colormap ( xcb_connection_t *xcb_connection, xcb_screen_t *xcb_screen )
|
||||
{
|
||||
int screen = DefaultScreen ( display );
|
||||
// Try to create TrueColor map
|
||||
if ( XMatchVisualInfo ( display, screen, 32, TrueColor, &vinfo ) ) {
|
||||
// Visual found, lets try to create map.
|
||||
map = XCreateColormap ( display, DefaultRootWindow ( display ), vinfo.visual, AllocNone );
|
||||
truecolor = TRUE;
|
||||
xcb_depth_iterator_t depth_iter;
|
||||
for ( depth_iter = xcb_screen_allowed_depths_iterator ( xcb_screen ); depth_iter.rem; xcb_depth_next ( &depth_iter ) ) {
|
||||
xcb_depth_t *d = depth_iter.data;
|
||||
|
||||
xcb_visualtype_iterator_t visual_iter;
|
||||
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;
|
||||
}
|
||||
if ( xcb_screen->root_visual == v->visual_id ) {
|
||||
root_depth = d;
|
||||
root_visual = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Failed to create map.
|
||||
// Use the defaults then.
|
||||
if ( map == None ) {
|
||||
truecolor = FALSE;
|
||||
// Two fields we use.
|
||||
vinfo.visual = DefaultVisual ( display, screen );
|
||||
vinfo.depth = DefaultDepth ( display, screen );
|
||||
map = DefaultColormap ( display, screen );
|
||||
if ( visual != NULL ) {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( visual == NULL ) {
|
||||
depth = root_depth;
|
||||
visual = root_visual;
|
||||
map = xcb_screen->default_colormap;
|
||||
}
|
||||
}
|
||||
|
||||
Color color_get ( Display *display, const char *const name, const char * const defn )
|
||||
Color color_get ( const char *const name )
|
||||
{
|
||||
char *copy = g_strdup ( name );
|
||||
char *cname = g_strstrip ( copy );
|
||||
XColor color = { 0, 0, 0, 0, 0, 0 };
|
||||
XColor def;
|
||||
char *copy = g_strdup ( name );
|
||||
char *cname = g_strstrip ( copy );
|
||||
|
||||
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.
|
||||
if ( strncmp ( cname, "argb:", 5 ) == 0 ) {
|
||||
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 );
|
||||
|
||||
Color ret = {
|
||||
.red = color.red / 65535.0,
|
||||
.green = color.green / 65535.0,
|
||||
.blue = color.blue / 65535.0,
|
||||
.alpha = ( ( color.pixel & 0xFF000000 ) >> 24 ) / 255.0,
|
||||
.red = color.r / 255.0,
|
||||
.green = color.g / 255.0,
|
||||
.blue = color.b / 255.0,
|
||||
.alpha = color.a / 255.0,
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
@ -619,16 +633,16 @@ void color_cache_reset ( void )
|
|||
color_cache[BORDER].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 ( !config.color_enabled ) {
|
||||
color_cache[BACKGROUND].color = color_get ( display, config.menu_bg, "black" );
|
||||
color_cache[BACKGROUND].color = color_get ( config.menu_bg );
|
||||
}
|
||||
else {
|
||||
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
|
||||
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 );
|
||||
}
|
||||
|
@ -638,16 +652,16 @@ void color_background ( Display *display, cairo_t *d )
|
|||
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 ( !config.color_enabled ) {
|
||||
color_cache[BORDER].color = color_get ( display, config.menu_bc, "white" );
|
||||
color_cache[BORDER].color = color_get ( config.menu_bc );
|
||||
}
|
||||
else {
|
||||
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
|
||||
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 );
|
||||
}
|
||||
|
@ -656,19 +670,19 @@ void color_border ( Display *display, cairo_t *d )
|
|||
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 ( !config.color_enabled ) {
|
||||
color_cache[SEPARATOR].color = color_get ( display, config.menu_bc, "white" );
|
||||
color_cache[SEPARATOR].color = color_get ( config.menu_bc );
|
||||
}
|
||||
else {
|
||||
gchar **vals = g_strsplit ( config.color_window, ",", 3 );
|
||||
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 ) {
|
||||
color_cache[SEPARATOR].color = color_get ( display, vals[1], "white" );
|
||||
color_cache[SEPARATOR].color = color_get ( vals[1] );
|
||||
}
|
||||
g_strfreev ( vals );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue