Continue work on wayland mode

- Fix mouse support
- Handle key repeats
- Positioning
- Fix periodic count updates
This commit is contained in:
lbonn 2020-05-28 01:30:41 +02:00
parent 7d94413675
commit 97ea1c6d0b
4 changed files with 237 additions and 218 deletions

View file

@ -115,4 +115,7 @@ void display_buffer_pool_free(display_buffer_pool *pool);
cairo_surface_t *display_buffer_pool_get_next_buffer(display_buffer_pool *pool); cairo_surface_t *display_buffer_pool_get_next_buffer(display_buffer_pool *pool);
void display_surface_commit(cairo_surface_t *surface); void display_surface_commit(cairo_surface_t *surface);
gboolean display_get_surface_dimensions ( int *width, int *height );
void display_set_surface_dimensions ( int width, int height, int loc );
#endif #endif

View file

@ -16,20 +16,8 @@ typedef enum {
_WAYLAND_GLOBAL_SIZE, _WAYLAND_GLOBAL_SIZE,
} wayland_global_name; } wayland_global_name;
#if 0
typedef enum {
WIDGET_MODMASK_SHIFT = (1 << WIDGET_MOD_SHIFT),
WIDGET_MODMASK_CONTROL = (1 << WIDGET_MOD_CONTROL),
WIDGET_MODMASK_ALT = (1 << WIDGET_MOD_ALT),
WIDGET_MODMASK_META = (1 << WIDGET_MOD_META),
WIDGET_MODMASK_SUPER = (1 << WIDGET_MOD_SUPER),
WIDGET_MODMASK_HYPER = (1 << WIDGET_MOD_HYPER),
WIDGET_MODMASK_ALL = (WIDGET_MODMASK_SHIFT | WIDGET_MODMASK_CONTROL | WIDGET_MODMASK_ALT | WIDGET_MODMASK_META | WIDGET_MODMASK_SUPER | WIDGET_MODMASK_HYPER)
} widget_modifier_mask;
#endif
typedef struct { typedef struct {
NkBindingsMouseButton button; uint32_t button;
char modifiers; char modifiers;
gint x, y; gint x, y;
gboolean pressed; gboolean pressed;
@ -86,9 +74,14 @@ struct _wayland_seat {
uint32_t global_name; uint32_t global_name;
struct wl_seat *seat; struct wl_seat *seat;
gchar *name; gchar *name;
struct {
xkb_keycode_t key;
GSource *source;
int32_t rate;
int32_t delay;
} repeat;
uint32_t serial; uint32_t serial;
struct wl_keyboard *keyboard; struct wl_keyboard *keyboard;
// xkb_stuff xkb;
struct wl_pointer *pointer; struct wl_pointer *pointer;
widget_button_event button; widget_button_event button;
widget_motion_event motion; widget_motion_event motion;

View file

@ -364,6 +364,52 @@ wayland_keyboard_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial
// TODO? // TODO?
} }
static gboolean
wayland_key_repeat(void *data)
{
wayland_seat *self = data;
if ( self->repeat.key == 0 ) {
self->repeat.source = NULL;
return G_SOURCE_REMOVE;
}
RofiViewState *state = rofi_view_get_active ( );
char *text = nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, self->repeat.key, NK_BINDINGS_KEY_STATE_PRESS );
if ( text != NULL ) {
rofi_view_handle_text ( state, text );
}
rofi_view_maybe_update( state );
return G_SOURCE_CONTINUE;
}
static gboolean
wayland_key_repeat_delay(void *data)
{
wayland_seat *self = data;
if ( self->repeat.key == 0 ) {
return FALSE;
}
RofiViewState *state = rofi_view_get_active ( );
char *text = nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, self->repeat.key, NK_BINDINGS_KEY_STATE_PRESS );
if ( text != NULL ) {
rofi_view_handle_text ( state, text );
}
guint source_id = g_timeout_add ( self->repeat.rate, wayland_key_repeat, data );
self->repeat.source = g_main_context_find_source_by_id ( NULL, source_id);
rofi_view_maybe_update( state );
return G_SOURCE_REMOVE;
}
static void static void
wayland_keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, enum wl_keyboard_key_state kstate) wayland_keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, enum wl_keyboard_key_state kstate)
{ {
@ -375,14 +421,30 @@ wayland_keyboard_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
wayland->last_seat = self; wayland->last_seat = self;
self->serial = serial; self->serial = serial;
xkb_keycode_t keycode = key + 8;
if ( kstate == WL_KEYBOARD_KEY_STATE_RELEASED ) { if ( kstate == WL_KEYBOARD_KEY_STATE_RELEASED ) {
nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, key + 8, NK_BINDINGS_KEY_STATE_RELEASE ); if ( keycode == self->repeat.key ) {
self->repeat.key = 0;
if ( self->repeat.source != NULL ) {
g_source_destroy ( self->repeat.source );
self->repeat.source = NULL;
}
}
nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, keycode, NK_BINDINGS_KEY_STATE_RELEASE );
} else if ( kstate == WL_KEYBOARD_KEY_STATE_PRESSED ) { } else if ( kstate == WL_KEYBOARD_KEY_STATE_PRESSED ) {
char *text = nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, key + 8, NK_BINDINGS_KEY_STATE_PRESS ); char *text = nk_bindings_seat_handle_key( wayland->bindings_seat, NULL, keycode, NK_BINDINGS_KEY_STATE_PRESS );
if ( text != NULL ) { if ( text != NULL ) {
rofi_view_handle_text ( state, text ); rofi_view_handle_text ( state, text );
} }
if ( self->repeat.source != NULL ) {
g_source_destroy ( self->repeat.source );
self->repeat.source = NULL;
}
self->repeat.key = keycode;
guint source_id = g_timeout_add ( self->repeat.delay, wayland_key_repeat_delay, data );
self->repeat.source = g_main_context_find_source_by_id ( NULL, source_id);
} }
rofi_view_maybe_update( state ); rofi_view_maybe_update( state );
@ -402,6 +464,13 @@ static void
wayland_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay) wayland_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard, int32_t rate, int32_t delay)
{ {
wayland_seat *self = data; wayland_seat *self = data;
self->repeat.key = 0;
self->repeat.rate = rate;
self->repeat.delay = delay;
if ( self->repeat.source != NULL ) {
g_source_destroy ( self->repeat.source );
self->repeat.source = NULL;
}
} }
static const struct wl_keyboard_listener wayland_keyboard_listener = { static const struct wl_keyboard_listener wayland_keyboard_listener = {
@ -452,7 +521,6 @@ static void
wayland_pointer_send_events(wayland_seat *self) wayland_pointer_send_events(wayland_seat *self)
{ {
RofiViewState *state = rofi_view_get_active (); RofiViewState *state = rofi_view_get_active ();
//widget_modifier_mask modmask = xkb_get_modmask(&self->xkb, 0);
if ( self->motion.x > -1 || self->motion.y > -1 ) if ( self->motion.x > -1 || self->motion.y > -1 )
{ {
@ -461,33 +529,42 @@ wayland_pointer_send_events(wayland_seat *self)
self->motion.y = -1; self->motion.y = -1;
} }
if ( self->button.button > 0 ) NkBindingsMouseButton button = -1;
switch ( self->button.button )
{ {
//rofi_view_handle_mouse_button(&self->button); case BTN_LEFT:
button = NK_BINDINGS_MOUSE_BUTTON_PRIMARY;
break;
case BTN_RIGHT:
button = NK_BINDINGS_MOUSE_BUTTON_SECONDARY;
break;
case BTN_MIDDLE:
button = NK_BINDINGS_MOUSE_BUTTON_MIDDLE;
break;
}
if ( self->button.button >= 0 )
{
if ( self->button.pressed ) {
rofi_view_handle_mouse_motion ( state, self->button.x, self->button.y );
nk_bindings_seat_handle_button ( wayland->bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_PRESS, self->button.time );
} else {
nk_bindings_seat_handle_button ( wayland->bindings_seat, NULL, button, NK_BINDINGS_BUTTON_STATE_RELEASE, self->button.time );
}
self->button.button = 0; self->button.button = 0;
} }
#if 0
if ( self->wheel.vertical != 0 ) if ( self->wheel.vertical != 0 )
{ {
rofi_mouse_wheel_direction direction = self->wheel.vertical < 0 ? ROFI_MOUSE_WHEEL_UP : ROFI_MOUSE_WHEEL_DOWN; nk_bindings_seat_handle_scroll( wayland->bindings_seat, NULL, NK_BINDINGS_SCROLL_AXIS_VERTICAL, self->wheel.vertical );
guint val = ABS(self->wheel.vertical);
do
rofi_view_mouse_navigation(direction);
while ( --val > 0 );
self->wheel.vertical = 0; self->wheel.vertical = 0;
} }
if ( self->wheel.horizontal != 0 ) if ( self->wheel.horizontal != 0 )
{ {
rofi_mouse_wheel_direction direction = self->wheel.horizontal < 0 ? ROFI_MOUSE_WHEEL_LEFT : ROFI_MOUSE_WHEEL_RIGHT; nk_bindings_seat_handle_scroll( wayland->bindings_seat, NULL, NK_BINDINGS_SCROLL_AXIS_HORIZONTAL, self->wheel.horizontal );
guint val = ABS(self->wheel.horizontal);
do
rofi_view_mouse_navigation(direction);
while ( --val > 0 );
self->wheel.horizontal = 0; self->wheel.horizontal = 0;
} }
#endif
rofi_view_maybe_update(state); rofi_view_maybe_update(state);
} }
@ -544,21 +621,7 @@ wayland_pointer_button(void *data, struct wl_pointer *pointer, uint32_t serial,
self->button.time = time; self->button.time = time;
self->button.pressed = (state == WL_POINTER_BUTTON_STATE_PRESSED); self->button.pressed = (state == WL_POINTER_BUTTON_STATE_PRESSED);
switch ( button ) self->button.button = button;
{
case BTN_LEFT:
self->button.button = NK_BINDINGS_MOUSE_BUTTON_PRIMARY;
break;
case BTN_RIGHT:
self->button.button = NK_BINDINGS_MOUSE_BUTTON_SECONDARY;
break;
case BTN_MIDDLE:
self->button.button = NK_BINDINGS_MOUSE_BUTTON_MIDDLE;
break;
}
if ( wl_pointer_get_version(self->pointer) >= WL_POINTER_FRAME_SINCE_VERSION )
return;
wayland_pointer_send_events(self); wayland_pointer_send_events(self);
} }
@ -568,9 +631,6 @@ wayland_pointer_axis(void *data, struct wl_pointer *pointer, uint32_t time, enum
{ {
wayland_seat *self = data; wayland_seat *self = data;
if ( wl_pointer_get_version(self->pointer) >= WL_POINTER_FRAME_SINCE_VERSION )
return;
switch ( axis ) switch ( axis )
{ {
case WL_POINTER_AXIS_VERTICAL_SCROLL: case WL_POINTER_AXIS_VERTICAL_SCROLL:
@ -640,6 +700,12 @@ wayland_keyboard_release(wayland_seat *self)
else else
wl_keyboard_destroy(self->keyboard); wl_keyboard_destroy(self->keyboard);
self->repeat.key = 0;
if ( self->repeat.source != NULL ) {
g_source_destroy ( self->repeat.source );
self->repeat.source = NULL;
}
self->keyboard = NULL; self->keyboard = NULL;
} }
@ -683,7 +749,6 @@ wayland_seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilitie
{ {
self->keyboard = wl_seat_get_keyboard(self->seat); self->keyboard = wl_seat_get_keyboard(self->seat);
wl_keyboard_add_listener(self->keyboard, &wayland_keyboard_listener, self); wl_keyboard_add_listener(self->keyboard, &wayland_keyboard_listener, self);
//self->xkb.context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
} }
else if ( ( ! ( capabilities & WL_SEAT_CAPABILITY_POINTER ) ) && ( self->keyboard != NULL ) ) else if ( ( ! ( capabilities & WL_SEAT_CAPABILITY_POINTER ) ) && ( self->keyboard != NULL ) )
wayland_keyboard_release(self); wayland_keyboard_release(self);
@ -787,7 +852,6 @@ wayland_registry_handle_global(void *data, struct wl_registry *registry, uint32_
seat->context = wayland; seat->context = wayland;
seat->global_name = name; seat->global_name = name;
seat->seat = wl_registry_bind(registry, name, &wl_seat_interface, MIN(version, WL_SEAT_INTERFACE_VERSION)); seat->seat = wl_registry_bind(registry, name, &wl_seat_interface, MIN(version, WL_SEAT_INTERFACE_VERSION));
g_hash_table_insert(wayland->seats, seat->seat, seat); g_hash_table_insert(wayland->seats, seat->seat, seat);
wl_seat_add_listener(seat->seat, &wayland_seat_listener, seat); wl_seat_add_listener(seat->seat, &wayland_seat_listener, seat);
@ -912,10 +976,6 @@ wayland_error(gpointer user_data)
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
static void
wayland_build_monitor_layout(void)
{
}
gboolean gboolean
display_setup(GMainLoop *main_loop, NkBindings *bindings) display_setup(GMainLoop *main_loop, NkBindings *bindings)
@ -943,7 +1003,14 @@ display_setup(GMainLoop *main_loop, NkBindings *bindings)
wl_registry_add_listener ( wayland->registry, &wayland_registry_listener, NULL ); wl_registry_add_listener ( wayland->registry, &wayland_registry_listener, NULL );
wl_display_roundtrip ( wayland->display ); wl_display_roundtrip ( wayland->display );
wayland_build_monitor_layout (); if ( wayland->compositor == NULL || wayland->shm == NULL || g_hash_table_size(wayland->outputs) == 0 || g_hash_table_size(wayland->seats) == 0 ) {
g_error( "Could not connect to wayland compositor" );
return FALSE;
}
if ( wayland->layer_shell == NULL ) {
g_error( "Rofi on wayland requires support for the layer shell protocol" );
return FALSE;
}
wayland->cursor.theme = wl_cursor_theme_load(wayland->cursor.theme_name, 32, wayland->shm); wayland->cursor.theme = wl_cursor_theme_load(wayland->cursor.theme_name, 32, wayland->shm);
if ( wayland->cursor.theme != NULL ) if ( wayland->cursor.theme != NULL )
@ -968,20 +1035,16 @@ display_setup(GMainLoop *main_loop, NkBindings *bindings)
return TRUE; return TRUE;
} }
gboolean display_late_setup ( void ) gboolean
display_late_setup ( void )
{ {
// TODO: move this in view? // note: ANCHOR_LEFT is needed to get the full window width
#if 0 zwlr_layer_surface_v1_set_anchor( wayland->wlr_surface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT );
zwlr_layer_surface_v1_set_size(wayland->wlr_surface, width, height);
zwlr_layer_surface_v1_set_anchor(wayland->wlr_surface, anchor);
zwlr_layer_surface_v1_set_exclusive_zone(wayland->wlr_surface, exclusive_zone);
zwlr_layer_surface_v1_set_margin(wayland->wlr_surface, margin_top, margin_right, margin_bottom, margin_left);
zwlr_layer_surface_v1_set_keyboard_interactivity( wayland->wlr_surface, keyboard_interactive);
#endif
zwlr_layer_surface_v1_set_anchor( wayland->wlr_surface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP );
zwlr_layer_surface_v1_set_keyboard_interactivity( wayland->wlr_surface, 1 ); zwlr_layer_surface_v1_set_keyboard_interactivity( wayland->wlr_surface, 1 );
zwlr_layer_surface_v1_add_listener( wayland->wlr_surface, &wayland_layer_shell_surface_listener, NULL ); zwlr_layer_surface_v1_add_listener( wayland->wlr_surface, &wayland_layer_shell_surface_listener, NULL );
// By setting 0 here, we'll get some useful sizes in the configure event
zwlr_layer_surface_v1_set_size(wayland->wlr_surface, 0, 0);
wl_surface_add_listener( wayland->surface, &wayland_surface_interface, wayland ); wl_surface_add_listener( wayland->surface, &wayland_surface_interface, wayland );
wl_surface_commit( wayland->surface ); wl_surface_commit( wayland->surface );
wl_display_roundtrip( wayland->display ); wl_display_roundtrip( wayland->display );
@ -990,6 +1053,60 @@ gboolean display_late_setup ( void )
return TRUE; return TRUE;
} }
gboolean
display_get_surface_dimensions ( int *width, int *height )
{
if ( wayland->layer_width != 0 ) {
if ( width != NULL )
*width = wayland->layer_width;
if ( height != NULL )
*height = wayland->layer_height;
return TRUE;
}
return FALSE;
}
void
display_set_surface_dimensions ( int width, int height, int loc )
{
wayland->layer_width = width;
wayland->layer_height = height;
zwlr_layer_surface_v1_set_size( wayland->wlr_surface, width, height );
uint32_t wlr_anchor = 0;
switch ( loc )
{
case WL_NORTH_WEST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
break;
case WL_NORTH:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
break;
case WL_NORTH_EAST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
break;
case WL_EAST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
break;
case WL_SOUTH_EAST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
break;
case WL_SOUTH:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
break;
case WL_SOUTH_WEST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
break;
case WL_WEST:
wlr_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
break;
case WL_CENTER:
default:
break;
}
zwlr_layer_surface_v1_set_anchor( wayland->wlr_surface, wlr_anchor );
}
void void
display_early_cleanup(void) display_early_cleanup(void)
{ {

View file

@ -82,22 +82,6 @@ RofiViewState *current_active_menu = NULL;
*/ */
struct struct
{ {
#if 0
/** main x11 windows */
xcb_window_t main_window;
/** surface containing the fake background. */
cairo_surface_t *fake_bg;
/** Draw context for main window */
xcb_gcontext_t gc;
/** Main X11 side pixmap to draw on. */
xcb_pixmap_t edit_pixmap;
/** Cairo Surface for edit_pixmap */
cairo_surface_t *edit_surf;
/** Drawable context for edit_surf */
cairo_t *edit_draw;
/** Indicate that fake background should be drawn relative to the window */
int fake_bgrel;
#endif
/** Main flags */ /** Main flags */
MenuFlags flags; MenuFlags flags;
/** List of stacked views */ /** List of stacked views */
@ -125,7 +109,9 @@ struct
void rofi_view_get_current_monitor ( int *width, int *height ) void rofi_view_get_current_monitor ( int *width, int *height )
{ {
display_get_surface_dimensions( width, height );
} }
static char * get_matching_state ( void ) static char * get_matching_state ( void )
{ {
if ( config.case_sensitive ) { if ( config.case_sensitive ) {
@ -163,22 +149,26 @@ void rofi_capture_screenshot ( void )
{ {
} }
static void rofi_view_update_prompt ( RofiViewState *state ) static gboolean rofi_view_repaint ( G_GNUC_UNUSED void * data )
{ {
if ( current_active_menu ) {
// Repaint the view (if needed).
// After a resize the edit_pixmap surface might not contain anything anymore.
// If we already re-painted, this does nothing.
rofi_view_maybe_update( current_active_menu );
CacheState.repaint_source = 0;
}
return G_SOURCE_REMOVE;
}
static void rofi_view_update_prompt ( RofiViewState *state )
{
if ( state->prompt ) {
const char *str = mode_get_display_name ( state->sw );
textbox_text ( state->prompt, str );
}
} }
/**
* Calculates the window position
*/
/** Convert the old location to the new location type.
* 123
* 804
* 765
*
* nw n ne
* w c e
* sw s se
*/
static const int loc_transtable[9] = { static const int loc_transtable[9] = {
WL_CENTER, WL_CENTER,
WL_NORTH | WL_WEST, WL_NORTH | WL_WEST,
@ -190,110 +180,16 @@ static const int loc_transtable[9] = {
WL_SOUTH | WL_WEST, WL_SOUTH | WL_WEST,
WL_WEST WL_WEST
}; };
#if 0
static void rofi_view_calculate_window_position ( RofiViewState *state )
{
int location = rofi_theme_get_position ( WIDGET ( state->main_window ), "location", loc_transtable[config.location] );
int anchor = location;
if ( !listview_get_fixed_num_lines ( state->list_view ) ) {
anchor = location;
if ( location == WL_CENTER ) {
anchor = WL_NORTH;
}
else if ( location == WL_EAST ) {
anchor = WL_NORTH_EAST;
}
else if ( location == WL_WEST ) {
anchor = WL_NORTH_WEST;
}
}
anchor = rofi_theme_get_position ( WIDGET ( state->main_window ), "anchor", anchor );
if ( CacheState.fullscreen ) { static int rofi_get_location ( RofiViewState *state )
state->x = CacheState.mon.x;
state->y = CacheState.mon.y;
return;
}
state->y = CacheState.mon.y + ( CacheState.mon.h ) / 2;
state->x = CacheState.mon.x + ( CacheState.mon.w ) / 2;
// Determine window location
switch ( location )
{ {
case WL_NORTH_WEST: return rofi_theme_get_position ( WIDGET ( state->main_window ), "location", loc_transtable[config.location] );
state->x = CacheState.mon.x;
/* FALLTHRU */
case WL_NORTH:
state->y = CacheState.mon.y;
break;
case WL_NORTH_EAST:
state->y = CacheState.mon.y;
/* FALLTHRU */
case WL_EAST:
state->x = CacheState.mon.x + CacheState.mon.w;
break;
case WL_SOUTH_EAST:
state->x = CacheState.mon.x + CacheState.mon.w;
/* FALLTHRU */
case WL_SOUTH:
state->y = CacheState.mon.y + CacheState.mon.h;
break;
case WL_SOUTH_WEST:
state->y = CacheState.mon.y + CacheState.mon.h;
/* FALLTHRU */
case WL_WEST:
state->x = CacheState.mon.x;
break;
case WL_CENTER:
;
/* FALLTHRU */
default:
break;
} }
switch ( anchor )
{
case WL_SOUTH_WEST:
state->y -= state->height;
break;
case WL_SOUTH:
state->x -= state->width / 2;
state->y -= state->height;
break;
case WL_SOUTH_EAST:
state->x -= state->width;
state->y -= state->height;
break;
case WL_NORTH_EAST:
state->x -= state->width;
break;
case WL_NORTH_WEST:
break;
case WL_NORTH:
state->x -= state->width / 2;
break;
case WL_EAST:
state->x -= state->width;
state->y -= state->height / 2;
break;
case WL_WEST:
state->y -= state->height / 2;
break;
case WL_CENTER:
state->y -= state->height / 2;
state->x -= state->width / 2;
break;
default:
break;
}
// Apply offset.
RofiDistance x = rofi_theme_get_distance ( WIDGET ( state->main_window ), "x-offset", config.x_offset );
RofiDistance y = rofi_theme_get_distance ( WIDGET ( state->main_window ), "y-offset", config.y_offset );
state->x += distance_get_pixel ( x, ROFI_ORIENTATION_HORIZONTAL );
state->y += distance_get_pixel ( y, ROFI_ORIENTATION_VERTICAL );
}
#endif
static void rofi_view_window_update_size ( RofiViewState * state ) static void rofi_view_window_update_size ( RofiViewState * state )
{ {
widget_resize ( WIDGET ( state->main_window ), state->width, state->height );
display_set_surface_dimensions ( state->width, state->height, rofi_get_location(state) );
} }
void rofi_view_set_size ( RofiViewState * state, gint width, gint height ) void rofi_view_set_size ( RofiViewState * state, gint width, gint height )
@ -329,10 +225,13 @@ static void rofi_view_reload_message_bar ( RofiViewState *state )
static gboolean rofi_view_reload_idle ( G_GNUC_UNUSED gpointer data ) static gboolean rofi_view_reload_idle ( G_GNUC_UNUSED gpointer data )
{ {
RofiViewState *state = rofi_view_get_active ();
if ( current_active_menu ) { if ( current_active_menu ) {
current_active_menu->reload = TRUE; current_active_menu->reload = TRUE;
current_active_menu->refilter = TRUE; current_active_menu->refilter = TRUE;
rofi_view_queue_redraw ();
rofi_view_maybe_update ( state );
} }
CacheState.idle_timeout = 0; CacheState.idle_timeout = 0;
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
@ -342,11 +241,19 @@ void rofi_view_reload ( void )
{ {
// @TODO add check if current view is equal to the callee // @TODO add check if current view is equal to the callee
if ( CacheState.idle_timeout == 0 ) { if ( CacheState.idle_timeout == 0 ) {
CacheState.idle_timeout = g_timeout_add ( 1000 / 10, rofi_view_reload_idle, NULL ); CacheState.idle_timeout = g_timeout_add ( 1000 / 15, rofi_view_reload_idle, NULL );
} }
} }
void rofi_view_queue_redraw ( void ) void rofi_view_queue_redraw ( void )
{ {
if ( current_active_menu && CacheState.repaint_source == 0 ) {
CacheState.count++;
g_debug ( "redraw %llu", CacheState.count );
widget_queue_redraw ( WIDGET ( current_active_menu->main_window ) );
CacheState.repaint_source = g_idle_add_full ( G_PRIORITY_HIGH_IDLE, rofi_view_repaint, NULL, NULL );
}
} }
void rofi_view_restart ( RofiViewState *state ) void rofi_view_restart ( RofiViewState *state )
@ -385,6 +292,16 @@ void rofi_view_set_active ( RofiViewState *state )
void rofi_view_set_selected_line ( RofiViewState *state, unsigned int selected_line ) void rofi_view_set_selected_line ( RofiViewState *state, unsigned int selected_line )
{ {
state->selected_line = selected_line;
// Find the line.
unsigned int selected = 0;
for ( unsigned int i = 0; ( ( state->selected_line ) ) < UINT32_MAX && !selected && i < state->filtered_lines; i++ ) {
if ( state->line_map[i] == ( state->selected_line ) ) {
selected = i;
break;
}
}
listview_set_selected ( state->list_view, selected );
} }
void rofi_view_free ( RofiViewState *state ) void rofi_view_free ( RofiViewState *state )
@ -576,8 +493,10 @@ static void rofi_view_calculate_window_width ( RofiViewState *state )
state->width += widget_padding_get_padding_width ( WIDGET ( state->main_window ) ); state->width += widget_padding_get_padding_width ( WIDGET ( state->main_window ) );
} }
else { else {
int width = 1920;
// Calculate as float to stop silly, big rounding down errors. // Calculate as float to stop silly, big rounding down errors.
state->width = config.menu_width < 101 ? ( /* FIXME: ??? what to use instead of monitor size here? */ 1000. / 100.0f ) * ( float ) config.menu_width : config.menu_width; display_get_surface_dimensions( &width, NULL );
state->width = config.menu_width < 101 ? ( (float)width / 100.0f ) * ( float ) config.menu_width : config.menu_width;
} }
// Use theme configured width, if set. // Use theme configured width, if set.
RofiDistance width = rofi_theme_get_distance ( WIDGET ( state->main_window ), "width", state->width ); RofiDistance width = rofi_theme_get_distance ( WIDGET ( state->main_window ), "width", state->width );
@ -1180,19 +1099,6 @@ void rofi_view_temp_configure_notify ( RofiViewState *state, xcb_configure_notif
{ {
} }
static gboolean rofi_view_repaint ( G_GNUC_UNUSED void * data )
{
if ( current_active_menu ) {
// Repaint the view (if needed).
// After a resize the edit_pixmap surface might not contain anything anymore.
// If we already re-painted, this does nothing.
rofi_view_update ( current_active_menu, FALSE );
CacheState.repaint_source = 0;
}
return FALSE;
// return (bench_update () == TRUE )? G_SOURCE_CONTINUE:G_SOURCE_REMOVE;
}
void rofi_view_frame_callback ( void ) void rofi_view_frame_callback ( void )
{ {
if ( CacheState.repaint_source == 0 ) { if ( CacheState.repaint_source == 0 ) {
@ -1202,11 +1108,11 @@ void rofi_view_frame_callback ( void )
static int rofi_view_calculate_height ( RofiViewState *state ) static int rofi_view_calculate_height ( RofiViewState *state )
{ {
/*
if ( CacheState.fullscreen == TRUE ) { if ( CacheState.fullscreen == TRUE ) {
return CacheState.mon.h; int height = 1080;
display_get_surface_dimensions( NULL, &height );
return height;
} }
*/
RofiDistance h = rofi_theme_get_distance ( WIDGET ( state->main_window ), "height", 0 ); RofiDistance h = rofi_theme_get_distance ( WIDGET ( state->main_window ), "height", 0 );
unsigned int height = distance_get_pixel ( h, ROFI_ORIENTATION_VERTICAL ); unsigned int height = distance_get_pixel ( h, ROFI_ORIENTATION_VERTICAL );