mirror of
https://github.com/davatorium/rofi.git
synced 2025-04-07 17:33:14 -04:00
Use libnkutils for keybindings
Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net>
This commit is contained in:
parent
6acf365420
commit
a9199e3e17
34 changed files with 644 additions and 802 deletions
.gitmodulesINSTALL.mdMakefile.amconfigure.ac
include
meson.buildsource
subprojects
test
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "libgwater"]
|
||||
path = subprojects/libgwater
|
||||
url = git://github.com/sardemff7/libgwater
|
||||
[submodule "libnkutils"]
|
||||
path = subprojects/libnkutils
|
||||
url = https://github.com/sardemff7/libnkutils
|
||||
|
|
|
@ -28,7 +28,7 @@ Rofi uses autotools (GNU Build system), for more information see
|
|||
* gmodule-2.0
|
||||
* gio-unix-2.0
|
||||
* libstartup-notification-1.0
|
||||
* libxkbcommon >= 0.5.0
|
||||
* libxkbcommon >= 0.4.1
|
||||
* libxkbcommon-x11
|
||||
* libxcb (sometimes split, you need libxcb, libxcb-xkb and libxcb-randr libxcb-xinerama)
|
||||
* xcb-util
|
||||
|
|
15
Makefile.am
15
Makefile.am
|
@ -1,11 +1,15 @@
|
|||
# Specify automake version.
|
||||
AUTOMAKE_OPTIONS = 1.11.3
|
||||
|
||||
ACLOCAL_AMFLAGS = -I subprojects/libgwater ${ACLOCAL_FLAGS}
|
||||
ACLOCAL_AMFLAGS = -I subprojects/libnkutils -I subprojects/libgwater ${ACLOCAL_FLAGS}
|
||||
|
||||
AM_YFLAGS = -d
|
||||
|
||||
noinst_LIBRARIES =
|
||||
EXTRA_DIST=
|
||||
check_PROGRAMS=
|
||||
TESTS=
|
||||
include $(top_srcdir)/subprojects/libnkutils/libnkutils-nolibtool.mk
|
||||
include $(top_srcdir)/libgwater-xcb-nolibtool.mk
|
||||
|
||||
##
|
||||
|
@ -114,6 +118,7 @@ rofi_SOURCES=\
|
|||
rofi_CFLAGS=\
|
||||
$(AM_CFLAGS)\
|
||||
$(glib_CFLAGS)\
|
||||
$(NKUTILS_CFLAGS)\
|
||||
$(GW_XCB_CFLAGS)\
|
||||
$(pango_CFLAGS)\
|
||||
$(libsn_CFLAGS)\
|
||||
|
@ -132,6 +137,7 @@ rofi_CFLAGS=\
|
|||
|
||||
rofi_LDADD=\
|
||||
$(glib_LIBS)\
|
||||
$(NKUTILS_LIBS)\
|
||||
$(GW_XCB_LIBS)\
|
||||
$(libsn_LIBS)\
|
||||
$(pango_LIBS)\
|
||||
|
@ -197,7 +203,7 @@ theme_DATA=\
|
|||
##
|
||||
# Extra DIST
|
||||
##
|
||||
EXTRA_DIST=\
|
||||
EXTRA_DIST+=\
|
||||
$(markdown_FILES)\
|
||||
$(markdown_SC_FILES)\
|
||||
Examples/i3_switch_workspaces.sh\
|
||||
|
@ -219,7 +225,7 @@ update-manpage: $(top_srcdir)/doc/rofi-manpage.markdown $(top_srcdir)/doc/rofi-t
|
|||
##
|
||||
# Rofi test program
|
||||
##
|
||||
check_PROGRAMS=\
|
||||
check_PROGRAMS+=\
|
||||
history_test\
|
||||
textbox_test\
|
||||
helper_test\
|
||||
|
@ -488,7 +494,7 @@ mode_test_SOURCES=\
|
|||
include/mode-private.h
|
||||
endif
|
||||
|
||||
TESTS=\
|
||||
TESTS+=\
|
||||
history_test\
|
||||
helper_test\
|
||||
helper_expand\
|
||||
|
@ -560,6 +566,7 @@ coverage-clean:
|
|||
|
||||
EXTRA_DIST += \
|
||||
doc/meson.build \
|
||||
subprojects/libnkutils/meson.build \
|
||||
subprojects/libgwater/xcb/meson.build \
|
||||
meson_options.txt \
|
||||
meson.build
|
||||
|
|
|
@ -116,9 +116,9 @@ PKG_PROG_PKG_CONFIG
|
|||
dnl ---------------------------------------------------------------------
|
||||
dnl PKG_CONFIG based dependencies
|
||||
dnl ---------------------------------------------------------------------
|
||||
NK_INIT([bindings])
|
||||
PKG_CHECK_MODULES([glib], [glib-2.0 >= 2.40 gio-unix-2.0 gmodule-2.0])
|
||||
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon >= 0.5.0 xkbcommon-x11 xcb-ewmh xcb-icccm xcb-xrm xcb-randr xcb-xinerama])
|
||||
PKG_CHECK_EXISTS([xkbcommon >= 0.7.0], [AC_DEFINE([XkBCOMMON_HAS_CONSUMED2], [1], [If xkbcommon has the consumed2 API])])
|
||||
GW_CHECK_XCB([xcb-aux xcb-xkb xkbcommon xkbcommon-x11 xcb-ewmh xcb-icccm xcb-xrm xcb-randr xcb-xinerama])
|
||||
PKG_CHECK_MODULES([pango], [pango pangocairo])
|
||||
PKG_CHECK_MODULES([cairo], [cairo cairo-xcb])
|
||||
PKG_CHECK_MODULES([libsn], [libstartup-notification-1.0 ])
|
||||
|
|
|
@ -28,19 +28,34 @@
|
|||
#ifndef ROFI_KEYB_H
|
||||
#define ROFI_KEYB_H
|
||||
|
||||
#include "nkutils-bindings.h"
|
||||
|
||||
/**
|
||||
* @defgroup KEYB KeyboardBindings
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCOPE_GLOBAL,
|
||||
SCOPE_MOUSE_LISTVIEW,
|
||||
SCOPE_MOUSE_LISTVIEW_ELEMENT,
|
||||
|
||||
#define SCOPE_MIN_FIXED SCOPE_MOUSE_EDITBOX
|
||||
SCOPE_MOUSE_EDITBOX,
|
||||
SCOPE_MOUSE_SCROLLBAR,
|
||||
SCOPE_MOUSE_SIDEBAR_MODI,
|
||||
#define SCOPE_MAX_FIXED SCOPE_MOUSE_SIDEBAR_MODI
|
||||
} BindingsScope;
|
||||
|
||||
/**
|
||||
* List of all possible actions that can be triggered by a keybinding.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/** Paste from primary clipboard */
|
||||
PASTE_PRIMARY = 0,
|
||||
PASTE_PRIMARY = 1,
|
||||
/** Paste from secondary clipboard */
|
||||
PASTE_SECONDARY,
|
||||
/** Clear the entry box. */
|
||||
|
@ -119,14 +134,36 @@ typedef enum
|
|||
SELECT_ELEMENT_8,
|
||||
SELECT_ELEMENT_9,
|
||||
SELECT_ELEMENT_10,
|
||||
NUM_ABE
|
||||
} KeyBindingAction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCROLL_LEFT = 1,
|
||||
SCROLL_RIGHT,
|
||||
SCROLL_DOWN,
|
||||
SCROLL_UP,
|
||||
} MouseBindingListviewAction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SELECT_HOVERED_ENTRY = 1,
|
||||
ACCEPT_HOVERED_ENTRY,
|
||||
ACCEPT_HOVERED_CUSTOM,
|
||||
} MouseBindingListviewElementAction;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MOUSE_CLICK_DOWN = 1,
|
||||
MOUSE_CLICK_UP,
|
||||
MOUSE_DCLICK_DOWN,
|
||||
MOUSE_DCLICK_UP,
|
||||
} MouseBindingMouseDefaultAction;
|
||||
|
||||
/**
|
||||
* Parse the keybindings.
|
||||
* This should be called after the setting system is initialized.
|
||||
*/
|
||||
gboolean parse_keys_abe ( void );
|
||||
gboolean parse_keys_abe ( NkBindings *bindings );
|
||||
|
||||
/**
|
||||
* Setup the keybindings
|
||||
|
@ -134,21 +171,5 @@ gboolean parse_keys_abe ( void );
|
|||
*/
|
||||
void setup_abe ( void );
|
||||
|
||||
/**
|
||||
* Cleanup.
|
||||
*/
|
||||
void cleanup_abe ( void );
|
||||
|
||||
/**
|
||||
* Find if a binding has been triggered.
|
||||
* @returns NUM_ABE if no key combo matches, a valid action otherwise.
|
||||
*/
|
||||
KeyBindingAction abe_find_action ( unsigned int mask, xkb_keysym_t key );
|
||||
|
||||
/**
|
||||
* Trigger keybinding on key release.
|
||||
*/
|
||||
void abe_trigger_release ( void );
|
||||
|
||||
/*@}*/
|
||||
#endif // ROFI_KEYB_H
|
||||
|
|
|
@ -37,19 +37,19 @@
|
|||
typedef enum
|
||||
{
|
||||
/** no highlight */
|
||||
HL_NONE = 0,
|
||||
HL_NONE = 0,
|
||||
/** bold */
|
||||
HL_BOLD = 1,
|
||||
HL_BOLD = 1,
|
||||
/** underline */
|
||||
HL_UNDERLINE = 2,
|
||||
HL_UNDERLINE = 2,
|
||||
/** strikethrough */
|
||||
HL_STRIKETHROUGH = 16,
|
||||
/** small caps */
|
||||
HL_SMALL_CAPS = 32,
|
||||
HL_SMALL_CAPS = 32,
|
||||
/** italic */
|
||||
HL_ITALIC = 4,
|
||||
HL_ITALIC = 4,
|
||||
/** color */
|
||||
HL_COLOR = 8
|
||||
HL_COLOR = 8
|
||||
} HighlightStyle;
|
||||
|
||||
/** Style of line */
|
||||
|
|
|
@ -122,8 +122,14 @@ struct RofiViewState
|
|||
/** Y position of the view */
|
||||
int y;
|
||||
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
} mouse;
|
||||
|
||||
/** Regexs used for matching */
|
||||
GRegex **tokens;
|
||||
GRegex **tokens;
|
||||
};
|
||||
/** @} */
|
||||
#endif
|
||||
|
|
|
@ -143,7 +143,7 @@ void rofi_view_restart ( RofiViewState *state );
|
|||
*
|
||||
* @returns TRUE if action was handled.
|
||||
*/
|
||||
gboolean rofi_view_trigger_action ( RofiViewState *state, KeyBindingAction action );
|
||||
gboolean rofi_view_trigger_action ( guint scope, gpointer user_data );
|
||||
|
||||
/**
|
||||
* @param state The handle to the view
|
||||
|
|
|
@ -66,7 +66,7 @@ typedef void ( *listview_update_callback )( textbox *tb, unsigned int entry, voi
|
|||
/**
|
||||
* Callback when a element is activated.
|
||||
*/
|
||||
typedef void ( *listview_mouse_activated_cb )( listview *, xcb_button_press_event_t *, void * );
|
||||
typedef void ( *listview_mouse_activated_cb )( listview *, gboolean, void * );
|
||||
|
||||
/**
|
||||
* @param name The name of the to be created widget.
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
typedef struct _scrollbar
|
||||
{
|
||||
widget widget;
|
||||
gboolean scrolling;
|
||||
unsigned int length;
|
||||
unsigned int pos;
|
||||
unsigned int pos_length;
|
||||
|
@ -88,7 +89,7 @@ void scrollbar_set_max_value ( scrollbar *sb, unsigned int max );
|
|||
*
|
||||
* Calculate the position of the click relative to the max value of bar
|
||||
*/
|
||||
unsigned int scrollbar_clicked ( const scrollbar *sb, int y );
|
||||
unsigned int scrollbar_scroll ( const scrollbar *sb, int y );
|
||||
|
||||
/*@}*/
|
||||
#endif // ROFI_SCROLLBAR_H
|
||||
|
|
|
@ -120,9 +120,10 @@ typedef enum
|
|||
* free with #widget_free
|
||||
* @returns a new #textbox
|
||||
*/
|
||||
textbox* textbox_create ( const char *name, TextboxFlags flags,
|
||||
TextBoxFontType tbft,
|
||||
const char *text );
|
||||
textbox* textbox_create_full ( WidgetType type, const char *name, TextboxFlags flags,
|
||||
TextBoxFontType tbft,
|
||||
const char *text );
|
||||
#define textbox_create( n, f, tbft, t ) textbox_create_full ( WIDGET_TYPE_UNKNOWN, n, f, tbft, t )
|
||||
/**
|
||||
* @param tb Handle to the textbox
|
||||
* @param tbft The style of font to render.
|
||||
|
|
|
@ -34,63 +34,67 @@
|
|||
*/
|
||||
struct _widget
|
||||
{
|
||||
/** The type of the widget */
|
||||
WidgetType type;
|
||||
/** X position relative to parent */
|
||||
short x;
|
||||
short x;
|
||||
/** Y position relative to parent */
|
||||
short y;
|
||||
short y;
|
||||
/** Width of the widget */
|
||||
short w;
|
||||
short w;
|
||||
/** Height of the widget */
|
||||
short h;
|
||||
short h;
|
||||
/** Padding */
|
||||
Padding def_margin;
|
||||
Padding def_padding;
|
||||
Padding def_border;
|
||||
Padding def_border_radius;
|
||||
Padding margin;
|
||||
Padding padding;
|
||||
Padding border;
|
||||
Padding border_radius;
|
||||
Padding def_margin;
|
||||
Padding def_padding;
|
||||
Padding def_border;
|
||||
Padding def_border_radius;
|
||||
Padding margin;
|
||||
Padding padding;
|
||||
Padding border;
|
||||
Padding border_radius;
|
||||
|
||||
/** enabled or not */
|
||||
gboolean enabled;
|
||||
gboolean enabled;
|
||||
/** Expand the widget when packed */
|
||||
gboolean expand;
|
||||
gboolean expand;
|
||||
/*** The packing index */
|
||||
int index;
|
||||
int index;
|
||||
/** Place widget at end of parent */
|
||||
gboolean end;
|
||||
gboolean end;
|
||||
/** Parent widget */
|
||||
struct _widget *parent;
|
||||
struct _widget *parent;
|
||||
/** Internal */
|
||||
gboolean need_redraw;
|
||||
gboolean need_redraw;
|
||||
/** get width of widget implementation function */
|
||||
int ( *get_width )( struct _widget * );
|
||||
int ( *get_width )( struct _widget * );
|
||||
/** get height of widget implementation function */
|
||||
int ( *get_height )( struct _widget * );
|
||||
int ( *get_height )( struct _widget * );
|
||||
/** draw widget implementation function */
|
||||
void ( *draw )( struct _widget *widget, cairo_t *draw );
|
||||
void ( *draw )( struct _widget *widget, cairo_t *draw );
|
||||
/** resize widget implementation function */
|
||||
void ( *resize )( struct _widget *, short, short );
|
||||
void ( *resize )( struct _widget *, short, short );
|
||||
/** update widget implementation function */
|
||||
void ( *update )( struct _widget * );
|
||||
void ( *update )( struct _widget * );
|
||||
|
||||
/** Handle mouse motion, used for dragging */
|
||||
gboolean ( *motion_notify )( struct _widget *, xcb_motion_notify_event_t * );
|
||||
gboolean ( *motion_notify )( struct _widget *, xcb_motion_notify_event_t * );
|
||||
|
||||
int ( *get_desired_height )( struct _widget * );
|
||||
int ( *get_desired_height )( struct _widget * );
|
||||
|
||||
/** widget clicked callback */
|
||||
widget_clicked_cb clicked;
|
||||
/** user data for clicked callback */
|
||||
void *clicked_cb_data;
|
||||
/** widget find_mouse_target callback */
|
||||
widget_find_mouse_target_cb find_mouse_target;
|
||||
/** widget trigger_action callback */
|
||||
widget_trigger_action_cb trigger_action;
|
||||
/** user data for find_mouse_target and trigger_action callback */
|
||||
void *trigger_action_cb_data;
|
||||
|
||||
/** Free widget callback */
|
||||
void ( *free )( struct _widget *widget );
|
||||
void ( *free )( struct _widget *widget );
|
||||
|
||||
/** Name of widget (used for theming) */
|
||||
char *name;
|
||||
const char *state;
|
||||
char *name;
|
||||
const char *state;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -100,7 +104,7 @@ struct _widget
|
|||
* Initializes the widget structure.
|
||||
*
|
||||
*/
|
||||
void widget_init ( widget *widget, const char *name );
|
||||
void widget_init ( widget *widget, WidgetType type, const char *name );
|
||||
|
||||
/**
|
||||
* @param widget The widget handle.
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <cairo.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xproto.h>
|
||||
#include "keyb.h"
|
||||
/**
|
||||
* @defgroup widget widget
|
||||
*
|
||||
|
@ -48,11 +49,18 @@
|
|||
* Structure is elaborated in widget-internal.h
|
||||
*/
|
||||
typedef struct _widget widget;
|
||||
typedef enum
|
||||
{
|
||||
WIDGET_TYPE_UNKNOWN,
|
||||
WIDGET_TYPE_LISTVIEW = SCOPE_MOUSE_LISTVIEW,
|
||||
WIDGET_TYPE_LISTVIEW_ELEMENT = SCOPE_MOUSE_LISTVIEW_ELEMENT,
|
||||
WIDGET_TYPE_EDITBOX = SCOPE_MOUSE_EDITBOX,
|
||||
WIDGET_TYPE_SCROLLBAR = SCOPE_MOUSE_SCROLLBAR,
|
||||
WIDGET_TYPE_SIDEBAR_MODI = SCOPE_MOUSE_SIDEBAR_MODI,
|
||||
} WidgetType;
|
||||
|
||||
/**
|
||||
* Callback for when widget is clicked.
|
||||
*/
|
||||
typedef gboolean ( *widget_clicked_cb )( widget *, xcb_button_press_event_t *, void * );
|
||||
typedef widget * ( *widget_find_mouse_target_cb )( widget *, WidgetType type, gint *x, gint *y );
|
||||
typedef gboolean ( *widget_trigger_action_cb )( widget *, guint action, gint x, gint y, void * );
|
||||
|
||||
/** Macro to get widget from an implementation (e.g. textbox/scrollbar) */
|
||||
#define WIDGET( a ) ( (widget *) ( a ) )
|
||||
|
@ -77,6 +85,14 @@ int widget_intersect ( const widget *widget, int x, int y );
|
|||
*/
|
||||
void widget_move ( widget *widget, short x, short y );
|
||||
|
||||
/**
|
||||
* @param widget Handle to widget
|
||||
*
|
||||
* Get the type of the widget.
|
||||
* @returns The type of the widget.
|
||||
*/
|
||||
WidgetType widget_type ( widget *widget );
|
||||
|
||||
/**
|
||||
* @param widget Handle to widget
|
||||
*
|
||||
|
@ -172,24 +188,35 @@ gboolean widget_need_redraw ( widget *wid );
|
|||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
* @param xbe The button press event
|
||||
* @param x A pointer to the x coordinate of the mouse event
|
||||
* @param y A pointer to the y coordinate of the mouse event
|
||||
*
|
||||
* Signal the widget that it has been clicked,
|
||||
* The click should have happened within the region of the widget, check with
|
||||
* ::widget_intersect.
|
||||
* Get the widget that should handle a mouse event.
|
||||
* @x and @y are adjusted to be relative to the widget.
|
||||
*
|
||||
* @returns returns TRUE if click is handled.
|
||||
* @returns returns the widget that should handle the mouse event.
|
||||
*/
|
||||
gboolean widget_clicked ( widget *wid, xcb_button_press_event_t *xbe );
|
||||
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y );
|
||||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
* @param cb The widget click callback
|
||||
* @param action The action to trigger
|
||||
* @param x A pointer to the x coordinate of the click
|
||||
* @param y A pointer to the y coordinate of the click
|
||||
*
|
||||
* Trigger an action on widget.
|
||||
* @x and @y are relative to the widget.
|
||||
*/
|
||||
gboolean widget_trigger_action ( widget *wid, guint action, gint x, gint y );
|
||||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
* @param cb The widget trigger action callback
|
||||
* @param udata the user data to pass to callback
|
||||
*
|
||||
* Override the widget clicked handler on widget.
|
||||
* Override the widget trigger action handler on widget.
|
||||
*/
|
||||
void widget_set_clicked_handler ( widget *wid, widget_clicked_cb cb, void *udata );
|
||||
void widget_set_trigger_action_handler ( widget *wid, widget_trigger_action_cb cb, void *udata );
|
||||
|
||||
/**
|
||||
* @param wid The widget handle
|
||||
|
|
|
@ -170,39 +170,13 @@ int take_keyboard ( xcb_window_t w, int iters );
|
|||
*/
|
||||
int take_pointer ( xcb_window_t w, int iters );
|
||||
|
||||
/**
|
||||
* @param mask The mask to canonilize
|
||||
*
|
||||
* @return The canonilized mask
|
||||
*/
|
||||
unsigned int x11_canonalize_mask ( unsigned int mask );
|
||||
|
||||
/**
|
||||
* @param xkb the xkb structure.
|
||||
*
|
||||
* Calculates the mask of all active modifier keys.
|
||||
*
|
||||
* @returns the mask describing all active modifier keys.
|
||||
*/
|
||||
unsigned int x11_get_current_mask ( xkb_stuff *xkb );
|
||||
|
||||
/**
|
||||
* @param combo String representing the key combo
|
||||
* @param mod [out] The modifier specified (or AnyModifier if not specified)
|
||||
* @param key [out] The key specified
|
||||
* @param release [out] If it should react on key-release, not key-press
|
||||
*
|
||||
* Parse key from user input string.
|
||||
*/
|
||||
gboolean x11_parse_key ( const char *combo, unsigned int *mod, xkb_keysym_t *key, gboolean *release, GString * );
|
||||
|
||||
/**
|
||||
* Setup several items required.
|
||||
* * Error handling,
|
||||
* * Numlock detection
|
||||
* * Cache
|
||||
*/
|
||||
void x11_setup ( xkb_stuff *xkb );
|
||||
void x11_setup ( void );
|
||||
|
||||
/**
|
||||
* Depth of visual
|
||||
|
@ -249,16 +223,6 @@ void x11_build_monitor_layout ( void );
|
|||
*/
|
||||
void x11_dump_monitor_layout ( void );
|
||||
|
||||
/**
|
||||
* @param mask the mask to check for key
|
||||
* @param key the key to check in mask
|
||||
*
|
||||
* Check if key is in the modifier mask.
|
||||
*
|
||||
* @returns TRUE if key is in the modifier mask
|
||||
*/
|
||||
int x11_modifier_active ( unsigned int mask, int key );
|
||||
|
||||
/**
|
||||
* @param window The X11 window to modify
|
||||
*
|
||||
|
|
|
@ -28,31 +28,18 @@
|
|||
#ifndef ROFI_XKB_INTERNAL_H
|
||||
#define ROFI_XKB_INTERNAL_H
|
||||
|
||||
#include "nkutils-bindings.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
|
||||
struct xkb_stuff
|
||||
{
|
||||
/** connection to the X server*/
|
||||
xcb_connection_t *xcb_connection;
|
||||
/** Keyboard context */
|
||||
struct xkb_context *context;
|
||||
xcb_connection_t *xcb_connection;
|
||||
/** Flag indicating first event */
|
||||
uint8_t first_event;
|
||||
uint8_t first_event;
|
||||
/** Keyboard device id */
|
||||
int32_t device_id;
|
||||
/** Current keymap */
|
||||
struct xkb_keymap *keymap;
|
||||
/** Keyboard state */
|
||||
struct xkb_state *state;
|
||||
/** Compose information */
|
||||
struct
|
||||
{
|
||||
/** Compose table */
|
||||
struct xkb_compose_table *table;
|
||||
/** Compose state */
|
||||
struct xkb_compose_state * state;
|
||||
} compose;
|
||||
int32_t device_id;
|
||||
NkBindings *bindings;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
13
meson.build
13
meson.build
|
@ -45,7 +45,7 @@ deps = [
|
|||
dependency('cairo'),
|
||||
dependency('pango'),
|
||||
dependency('pangocairo'),
|
||||
dependency('xkbcommon', version: '>= 0.5.0'),
|
||||
dependency('xkbcommon'),
|
||||
c_compiler.find_library('m', required: false),
|
||||
]
|
||||
|
||||
|
@ -101,6 +101,17 @@ header_conf.set_quoted('THEME_DIR', themedir)
|
|||
|
||||
config_h = configure_file(output: 'config.h', configuration: header_conf)
|
||||
|
||||
nk_modules = [
|
||||
'bindings=true',
|
||||
]
|
||||
nk = subproject('libnkutils', default_options: nk_modules)
|
||||
nk_options = nk.get_variable('nk_options')
|
||||
foreach o : nk_modules + nk_options
|
||||
if not nk_modules.contains(o) or not nk_options.contains(o)
|
||||
error('You must not change libnkutils options @0@ != @1@'.format('|'.join(nk_modules), '|'.join(nk_options)))
|
||||
endif
|
||||
endforeach
|
||||
deps += nk.get_variable('libnkutils')
|
||||
|
||||
install_headers([
|
||||
'include/mode.h',
|
||||
|
|
|
@ -206,7 +206,7 @@ static char **read_hosts_file ( char ** retv, unsigned int *length )
|
|||
// Reading one line per time.
|
||||
while ( getline ( &buffer, &buffer_length, fd ) > 0 ) {
|
||||
// Evaluate one line.
|
||||
unsigned int index = 0, ti = 0;
|
||||
unsigned int index = 0, ti = 0;
|
||||
char *token = buffer;
|
||||
|
||||
// Tokenize it.
|
||||
|
|
|
@ -256,7 +256,7 @@ GRegex **tokenize ( const char *input, int case_sensitive )
|
|||
}
|
||||
|
||||
char *saveptr = NULL, *token;
|
||||
GRegex **retv = NULL;
|
||||
GRegex **retv = NULL;
|
||||
if ( !config.tokenize ) {
|
||||
retv = g_malloc0 ( sizeof ( GRegex* ) * 2 );
|
||||
retv[0] = (GRegex *) create_regex ( input, case_sensitive );
|
||||
|
@ -885,8 +885,8 @@ int rofi_scorer_fuzzy_evaluate ( const char *pattern, glong plen, const char *st
|
|||
// uleft: value of the upper left cell; ulefts: maximum value of uleft and cells on the left. The arbitrary initial
|
||||
// values suppress warnings.
|
||||
int uleft = 0, ulefts = 0, left, lefts;
|
||||
const gchar *pit = pattern, *sit;
|
||||
enum CharClass prev = NON_WORD;
|
||||
const gchar *pit = pattern, *sit;
|
||||
enum CharClass prev = NON_WORD;
|
||||
for ( si = 0, sit = str; si < slen; si++, sit = g_utf8_next_char ( sit ) ) {
|
||||
enum CharClass cur = rofi_scorer_get_character_class ( g_utf8_get_char ( sit ) );
|
||||
score[si] = rofi_scorer_get_score_for ( prev, cur );
|
||||
|
|
292
source/keyb.c
292
source/keyb.c
|
@ -28,146 +28,136 @@
|
|||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include "rofi.h"
|
||||
#include "x11-helper.h"
|
||||
#include "xkb.h"
|
||||
#include "xkb-internal.h"
|
||||
#include "nkutils-bindings.h"
|
||||
#include "xrmoptions.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int modmask;
|
||||
xkb_keysym_t keysym;
|
||||
gboolean release;
|
||||
} KeyBinding;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
char *keystr;
|
||||
int num_bindings;
|
||||
KeyBinding *kb;
|
||||
guint id;
|
||||
guint scope;
|
||||
char *name;
|
||||
char *binding;
|
||||
char *comment;
|
||||
} ActionBindingEntry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
KeyBindingAction id;
|
||||
char *name;
|
||||
char *keybinding;
|
||||
char *comment;
|
||||
} DefaultBinding;
|
||||
|
||||
/**
|
||||
* Data structure holding all the action keybinding.
|
||||
*/
|
||||
ActionBindingEntry abe[NUM_ABE];
|
||||
|
||||
/**
|
||||
* LIST OF DEFAULT SETTINGS
|
||||
*/
|
||||
DefaultBinding bindings[NUM_ABE] =
|
||||
ActionBindingEntry rofi_bindings[] =
|
||||
{
|
||||
{ .id = PASTE_PRIMARY, .name = "kb-primary-paste", .keybinding = "Control+V,Shift+Insert", .comment = "Paste primary selection" },
|
||||
{ .id = PASTE_SECONDARY, .name = "kb-secondary-paste", .keybinding = "Control+v,Insert", .comment = "Paste clipboard" },
|
||||
{ .id = CLEAR_LINE, .name = "kb-clear-line", .keybinding = "Control+w", .comment = "Clear input line" },
|
||||
{ .id = MOVE_FRONT, .name = "kb-move-front", .keybinding = "Control+a", .comment = "Beginning of line" },
|
||||
{ .id = MOVE_END, .name = "kb-move-end", .keybinding = "Control+e", .comment = "End of line" },
|
||||
{ .id = MOVE_WORD_BACK, .name = "kb-move-word-back", .keybinding = "Alt+b", .comment = "Move back one word" },
|
||||
{ .id = MOVE_WORD_FORWARD, .name = "kb-move-word-forward", .keybinding = "Alt+f", .comment = "Move forward one word" },
|
||||
{ .id = MOVE_CHAR_BACK, .name = "kb-move-char-back", .keybinding = "Left,Control+b", .comment = "Move back one char" },
|
||||
{ .id = MOVE_CHAR_FORWARD, .name = "kb-move-char-forward", .keybinding = "Right,Control+f", .comment = "Move forward one char" },
|
||||
{ .id = REMOVE_WORD_BACK, .name = "kb-remove-word-back", .keybinding = "Control+Alt+h,Control+BackSpace", .comment = "Delete previous word" },
|
||||
{ .id = REMOVE_WORD_FORWARD, .name = "kb-remove-word-forward", .keybinding = "Control+Alt+d", .comment = "Delete next word" },
|
||||
{ .id = REMOVE_CHAR_FORWARD, .name = "kb-remove-char-forward", .keybinding = "Delete,Control+d", .comment = "Delete next char" },
|
||||
{ .id = REMOVE_CHAR_BACK, .name = "kb-remove-char-back", .keybinding = "BackSpace,Control+h", .comment = "Delete previous char" },
|
||||
{ .id = REMOVE_TO_EOL, .name = "kb-remove-to-eol", .keybinding = "Control+k", .comment = "Delete till the end of line" },
|
||||
{ .id = REMOVE_TO_SOL, .name = "kb-remove-to-sol", .keybinding = "Control+u", .comment = "Delete till the start of line" },
|
||||
{ .id = ACCEPT_ENTRY, .name = "kb-accept-entry", .keybinding = "Control+j,Control+m,Return,KP_Enter", .comment = "Accept entry" },
|
||||
{ .id = ACCEPT_CUSTOM, .name = "kb-accept-custom", .keybinding = "Control+Return", .comment = "Use entered text as command (in ssh/run modi)" },
|
||||
{ .id = ACCEPT_ALT, .name = "kb-accept-alt", .keybinding = "Shift+Return", .comment = "Use alternate accept command." },
|
||||
{ .id = DELETE_ENTRY, .name = "kb-delete-entry", .keybinding = "Shift+Delete", .comment = "Delete entry from history" },
|
||||
{ .id = MODE_NEXT, .name = "kb-mode-next", .keybinding = "Shift+Right,Control+Tab", .comment = "Switch to the next mode." },
|
||||
{ .id = MODE_PREVIOUS, .name = "kb-mode-previous", .keybinding = "Shift+Left,Control+ISO_Left_Tab", .comment = "Switch to the previous mode." },
|
||||
{ .id = ROW_LEFT, .name = "kb-row-left", .keybinding = "Control+Page_Up", .comment = "Go to the previous column" },
|
||||
{ .id = ROW_RIGHT, .name = "kb-row-right", .keybinding = "Control+Page_Down", .comment = "Go to the next column" },
|
||||
{ .id = ROW_UP, .name = "kb-row-up", .keybinding = "Up,Control+p,ISO_Left_Tab", .comment = "Select previous entry" },
|
||||
{ .id = ROW_DOWN, .name = "kb-row-down", .keybinding = "Down,Control+n", .comment = "Select next entry" },
|
||||
{ .id = ROW_TAB, .name = "kb-row-tab", .keybinding = "Tab", .comment = "Go to next row, if one left, accept it, if no left next mode." },
|
||||
{ .id = PAGE_PREV, .name = "kb-page-prev", .keybinding = "Page_Up", .comment = "Go to the previous page" },
|
||||
{ .id = PAGE_NEXT, .name = "kb-page-next", .keybinding = "Page_Down", .comment = "Go to the next page" },
|
||||
{ .id = ROW_FIRST, .name = "kb-row-first", .keybinding = "Home,KP_Home", .comment = "Go to the first entry" },
|
||||
{ .id = ROW_LAST, .name = "kb-row-last", .keybinding = "End,KP_End", .comment = "Go to the last entry" },
|
||||
{ .id = ROW_SELECT, .name = "kb-row-select", .keybinding = "Control+space", .comment = "Set selected item as input text" },
|
||||
{ .id = SCREENSHOT, .name = "kb-screenshot", .keybinding = "Alt+S", .comment = "Take a screenshot of the rofi window" },
|
||||
{ .id = TOGGLE_CASE_SENSITIVITY, .name = "kb-toggle-case-sensitivity", .keybinding = "grave,dead_grave", .comment = "Toggle case sensitivity" },
|
||||
{ .id = TOGGLE_SORT, .name = "kb-toggle-sort", .keybinding = "Alt+grave", .comment = "Toggle sort" },
|
||||
{ .id = CANCEL, .name = "kb-cancel", .keybinding = "Escape,Control+g,Control+bracketleft", .comment = "Quit rofi" },
|
||||
{ .id = CUSTOM_1, .name = "kb-custom-1", .keybinding = "Alt+1", .comment = "Custom keybinding 1" },
|
||||
{ .id = CUSTOM_2, .name = "kb-custom-2", .keybinding = "Alt+2", .comment = "Custom keybinding 2" },
|
||||
{ .id = CUSTOM_3, .name = "kb-custom-3", .keybinding = "Alt+3", .comment = "Custom keybinding 3" },
|
||||
{ .id = CUSTOM_4, .name = "kb-custom-4", .keybinding = "Alt+4", .comment = "Custom keybinding 4" },
|
||||
{ .id = CUSTOM_5, .name = "kb-custom-5", .keybinding = "Alt+5", .comment = "Custom Keybinding 5" },
|
||||
{ .id = CUSTOM_6, .name = "kb-custom-6", .keybinding = "Alt+6", .comment = "Custom keybinding 6" },
|
||||
{ .id = CUSTOM_7, .name = "kb-custom-7", .keybinding = "Alt+7", .comment = "Custom Keybinding 7" },
|
||||
{ .id = CUSTOM_8, .name = "kb-custom-8", .keybinding = "Alt+8", .comment = "Custom keybinding 8" },
|
||||
{ .id = CUSTOM_9, .name = "kb-custom-9", .keybinding = "Alt+9", .comment = "Custom keybinding 9" },
|
||||
{ .id = CUSTOM_10, .name = "kb-custom-10", .keybinding = "Alt+0", .comment = "Custom keybinding 10" },
|
||||
{ .id = CUSTOM_11, .name = "kb-custom-11", .keybinding = "Alt+exclam", .comment = "Custom keybinding 11" },
|
||||
{ .id = CUSTOM_12, .name = "kb-custom-12", .keybinding = "Alt+at", .comment = "Custom keybinding 12" },
|
||||
{ .id = CUSTOM_13, .name = "kb-custom-13", .keybinding = "Alt+numbersign", .comment = "Csutom keybinding 13" },
|
||||
{ .id = CUSTOM_14, .name = "kb-custom-14", .keybinding = "Alt+dollar", .comment = "Custom keybinding 14" },
|
||||
{ .id = CUSTOM_15, .name = "kb-custom-15", .keybinding = "Alt+percent", .comment = "Custom keybinding 15" },
|
||||
{ .id = CUSTOM_16, .name = "kb-custom-16", .keybinding = "Alt+dead_circumflex", .comment = "Custom keybinding 16" },
|
||||
{ .id = CUSTOM_17, .name = "kb-custom-17", .keybinding = "Alt+ampersand", .comment = "Custom keybinding 17" },
|
||||
{ .id = CUSTOM_18, .name = "kb-custom-18", .keybinding = "Alt+asterisk", .comment = "Custom keybinding 18" },
|
||||
{ .id = CUSTOM_19, .name = "kb-custom-19", .keybinding = "Alt+parenleft", .comment = "Custom Keybinding 19" },
|
||||
{ .id = SELECT_ELEMENT_1, .name = "kb-select-1", .keybinding = "Super+1", .comment = "Select row 1" },
|
||||
{ .id = SELECT_ELEMENT_2, .name = "kb-select-2", .keybinding = "Super+2", .comment = "Select row 2" },
|
||||
{ .id = SELECT_ELEMENT_3, .name = "kb-select-3", .keybinding = "Super+3", .comment = "Select row 3" },
|
||||
{ .id = SELECT_ELEMENT_4, .name = "kb-select-4", .keybinding = "Super+4", .comment = "Select row 4" },
|
||||
{ .id = SELECT_ELEMENT_5, .name = "kb-select-5", .keybinding = "Super+5", .comment = "Select row 5" },
|
||||
{ .id = SELECT_ELEMENT_6, .name = "kb-select-6", .keybinding = "Super+6", .comment = "Select row 6" },
|
||||
{ .id = SELECT_ELEMENT_7, .name = "kb-select-7", .keybinding = "Super+7", .comment = "Select row 7" },
|
||||
{ .id = SELECT_ELEMENT_8, .name = "kb-select-8", .keybinding = "Super+8", .comment = "Select row 8" },
|
||||
{ .id = SELECT_ELEMENT_9, .name = "kb-select-9", .keybinding = "Super+9", .comment = "Select row 9" },
|
||||
{ .id = SELECT_ELEMENT_10, .name = "kb-select-10", .keybinding = "Super+0", .comment = "Select row 10" },
|
||||
{ .id = PASTE_PRIMARY, .name = "kb-primary-paste", .binding = "Control+V,Shift+Insert", .comment = "Paste primary selection" },
|
||||
{ .id = PASTE_SECONDARY, .name = "kb-secondary-paste", .binding = "Control+v,Insert", .comment = "Paste clipboard" },
|
||||
{ .id = CLEAR_LINE, .name = "kb-clear-line", .binding = "Control+w", .comment = "Clear input line" },
|
||||
{ .id = MOVE_FRONT, .name = "kb-move-front", .binding = "Control+a", .comment = "Beginning of line" },
|
||||
{ .id = MOVE_END, .name = "kb-move-end", .binding = "Control+e", .comment = "End of line" },
|
||||
{ .id = MOVE_WORD_BACK, .name = "kb-move-word-back", .binding = "Alt+b", .comment = "Move back one word" },
|
||||
{ .id = MOVE_WORD_FORWARD, .name = "kb-move-word-forward", .binding = "Alt+f", .comment = "Move forward one word" },
|
||||
{ .id = MOVE_CHAR_BACK, .name = "kb-move-char-back", .binding = "Left,Control+b", .comment = "Move back one char" },
|
||||
{ .id = MOVE_CHAR_FORWARD, .name = "kb-move-char-forward", .binding = "Right,Control+f", .comment = "Move forward one char" },
|
||||
{ .id = REMOVE_WORD_BACK, .name = "kb-remove-word-back", .binding = "Control+Alt+h,Control+BackSpace", .comment = "Delete previous word" },
|
||||
{ .id = REMOVE_WORD_FORWARD, .name = "kb-remove-word-forward", .binding = "Control+Alt+d", .comment = "Delete next word" },
|
||||
{ .id = REMOVE_CHAR_FORWARD, .name = "kb-remove-char-forward", .binding = "Delete,Control+d", .comment = "Delete next char" },
|
||||
{ .id = REMOVE_CHAR_BACK, .name = "kb-remove-char-back", .binding = "BackSpace,Control+h", .comment = "Delete previous char" },
|
||||
{ .id = REMOVE_TO_EOL, .name = "kb-remove-to-eol", .binding = "Control+k", .comment = "Delete till the end of line" },
|
||||
{ .id = REMOVE_TO_SOL, .name = "kb-remove-to-sol", .binding = "Control+u", .comment = "Delete till the start of line" },
|
||||
{ .id = ACCEPT_ENTRY, .name = "kb-accept-entry", .binding = "Control+j,Control+m,Return,KP_Enter", .comment = "Accept entry" },
|
||||
{ .id = ACCEPT_CUSTOM, .name = "kb-accept-custom", .binding = "Control+Return", .comment = "Use entered text as command (in ssh/run modi)" },
|
||||
{ .id = ACCEPT_ALT, .name = "kb-accept-alt", .binding = "Shift+Return", .comment = "Use alternate accept command." },
|
||||
{ .id = DELETE_ENTRY, .name = "kb-delete-entry", .binding = "Shift+Delete", .comment = "Delete entry from history" },
|
||||
{ .id = MODE_NEXT, .name = "kb-mode-next", .binding = "Shift+Right,Control+Tab", .comment = "Switch to the next mode." },
|
||||
{ .id = MODE_PREVIOUS, .name = "kb-mode-previous", .binding = "Shift+Left,Control+ISO_Left_Tab", .comment = "Switch to the previous mode." },
|
||||
{ .id = ROW_LEFT, .name = "kb-row-left", .binding = "Control+Page_Up", .comment = "Go to the previous column" },
|
||||
{ .id = ROW_RIGHT, .name = "kb-row-right", .binding = "Control+Page_Down", .comment = "Go to the next column" },
|
||||
{ .id = ROW_UP, .name = "kb-row-up", .binding = "Up,Control+p,ISO_Left_Tab", .comment = "Select previous entry" },
|
||||
{ .id = ROW_DOWN, .name = "kb-row-down", .binding = "Down,Control+n", .comment = "Select next entry" },
|
||||
{ .id = ROW_TAB, .name = "kb-row-tab", .binding = "Tab", .comment = "Go to next row, if one left, accept it, if no left next mode." },
|
||||
{ .id = PAGE_PREV, .name = "kb-page-prev", .binding = "Page_Up", .comment = "Go to the previous page" },
|
||||
{ .id = PAGE_NEXT, .name = "kb-page-next", .binding = "Page_Down", .comment = "Go to the next page" },
|
||||
{ .id = ROW_FIRST, .name = "kb-row-first", .binding = "Home,KP_Home", .comment = "Go to the first entry" },
|
||||
{ .id = ROW_LAST, .name = "kb-row-last", .binding = "End,KP_End", .comment = "Go to the last entry" },
|
||||
{ .id = ROW_SELECT, .name = "kb-row-select", .binding = "Control+space", .comment = "Set selected item as input text" },
|
||||
{ .id = SCREENSHOT, .name = "kb-screenshot", .binding = "Alt+S", .comment = "Take a screenshot of the rofi window" },
|
||||
{ .id = TOGGLE_CASE_SENSITIVITY, .name = "kb-toggle-case-sensitivity", .binding = "grave,dead_grave", .comment = "Toggle case sensitivity" },
|
||||
{ .id = TOGGLE_SORT, .name = "kb-toggle-sort", .binding = "Alt+grave", .comment = "Toggle sort" },
|
||||
{ .id = CANCEL, .name = "kb-cancel", .binding = "Escape,Control+g,Control+bracketleft", .comment = "Quit rofi" },
|
||||
{ .id = CUSTOM_1, .name = "kb-custom-1", .binding = "Alt+1", .comment = "Custom keybinding 1" },
|
||||
{ .id = CUSTOM_2, .name = "kb-custom-2", .binding = "Alt+2", .comment = "Custom keybinding 2" },
|
||||
{ .id = CUSTOM_3, .name = "kb-custom-3", .binding = "Alt+3", .comment = "Custom keybinding 3" },
|
||||
{ .id = CUSTOM_4, .name = "kb-custom-4", .binding = "Alt+4", .comment = "Custom keybinding 4" },
|
||||
{ .id = CUSTOM_5, .name = "kb-custom-5", .binding = "Alt+5", .comment = "Custom Keybinding 5" },
|
||||
{ .id = CUSTOM_6, .name = "kb-custom-6", .binding = "Alt+6", .comment = "Custom keybinding 6" },
|
||||
{ .id = CUSTOM_7, .name = "kb-custom-7", .binding = "Alt+7", .comment = "Custom Keybinding 7" },
|
||||
{ .id = CUSTOM_8, .name = "kb-custom-8", .binding = "Alt+8", .comment = "Custom keybinding 8" },
|
||||
{ .id = CUSTOM_9, .name = "kb-custom-9", .binding = "Alt+9", .comment = "Custom keybinding 9" },
|
||||
{ .id = CUSTOM_10, .name = "kb-custom-10", .binding = "Alt+0", .comment = "Custom keybinding 10" },
|
||||
{ .id = CUSTOM_11, .name = "kb-custom-11", .binding = "Alt+exclam", .comment = "Custom keybinding 11" },
|
||||
{ .id = CUSTOM_12, .name = "kb-custom-12", .binding = "Alt+at", .comment = "Custom keybinding 12" },
|
||||
{ .id = CUSTOM_13, .name = "kb-custom-13", .binding = "Alt+numbersign", .comment = "Csutom keybinding 13" },
|
||||
{ .id = CUSTOM_14, .name = "kb-custom-14", .binding = "Alt+dollar", .comment = "Custom keybinding 14" },
|
||||
{ .id = CUSTOM_15, .name = "kb-custom-15", .binding = "Alt+percent", .comment = "Custom keybinding 15" },
|
||||
{ .id = CUSTOM_16, .name = "kb-custom-16", .binding = "Alt+dead_circumflex", .comment = "Custom keybinding 16" },
|
||||
{ .id = CUSTOM_17, .name = "kb-custom-17", .binding = "Alt+ampersand", .comment = "Custom keybinding 17" },
|
||||
{ .id = CUSTOM_18, .name = "kb-custom-18", .binding = "Alt+asterisk", .comment = "Custom keybinding 18" },
|
||||
{ .id = CUSTOM_19, .name = "kb-custom-19", .binding = "Alt+parenleft", .comment = "Custom Keybinding 19" },
|
||||
{ .id = SELECT_ELEMENT_1, .name = "kb-select-1", .binding = "Super+1", .comment = "Select row 1" },
|
||||
{ .id = SELECT_ELEMENT_2, .name = "kb-select-2", .binding = "Super+2", .comment = "Select row 2" },
|
||||
{ .id = SELECT_ELEMENT_3, .name = "kb-select-3", .binding = "Super+3", .comment = "Select row 3" },
|
||||
{ .id = SELECT_ELEMENT_4, .name = "kb-select-4", .binding = "Super+4", .comment = "Select row 4" },
|
||||
{ .id = SELECT_ELEMENT_5, .name = "kb-select-5", .binding = "Super+5", .comment = "Select row 5" },
|
||||
{ .id = SELECT_ELEMENT_6, .name = "kb-select-6", .binding = "Super+6", .comment = "Select row 6" },
|
||||
{ .id = SELECT_ELEMENT_7, .name = "kb-select-7", .binding = "Super+7", .comment = "Select row 7" },
|
||||
{ .id = SELECT_ELEMENT_8, .name = "kb-select-8", .binding = "Super+8", .comment = "Select row 8" },
|
||||
{ .id = SELECT_ELEMENT_9, .name = "kb-select-9", .binding = "Super+9", .comment = "Select row 9" },
|
||||
{ .id = SELECT_ELEMENT_10, .name = "kb-select-10", .binding = "Super+0", .comment = "Select row 10" },
|
||||
|
||||
/* Mouse-aware bindings */
|
||||
|
||||
{ .id = SCROLL_LEFT, .scope = SCOPE_MOUSE_LISTVIEW, .name = "ml-row-left", .binding = "Mouse6", .comment = "Go to the previous column" },
|
||||
{ .id = SCROLL_RIGHT, .scope = SCOPE_MOUSE_LISTVIEW, .name = "ml-row-right", .binding = "Mouse7", .comment = "Go to the next column" },
|
||||
{ .id = SCROLL_UP, .scope = SCOPE_MOUSE_LISTVIEW, .name = "ml-row-up", .binding = "Mouse4", .comment = "Select previous entry" },
|
||||
{ .id = SCROLL_DOWN, .scope = SCOPE_MOUSE_LISTVIEW, .name = "ml-row-down", .binding = "Mouse5", .comment = "Select next entry" },
|
||||
|
||||
{ .id = SELECT_HOVERED_ENTRY, .scope = SCOPE_MOUSE_LISTVIEW_ELEMENT, .name = "me-select-entry", .binding = "Mouse1", .comment = "Select hovered row" },
|
||||
{ .id = ACCEPT_HOVERED_ENTRY, .scope = SCOPE_MOUSE_LISTVIEW_ELEMENT, .name = "me-accept-entry", .binding = "MouseD1", .comment = "Accept hovered row" },
|
||||
{ .id = ACCEPT_HOVERED_CUSTOM, .scope = SCOPE_MOUSE_LISTVIEW_ELEMENT, .name = "me-accept-custom", .binding = "Control+MouseD1", .comment = "Accept hovered row with custom action" },
|
||||
|
||||
/* Sentinel */
|
||||
{ .id = 0 }
|
||||
};
|
||||
|
||||
static const gchar *mouse_default_bindings[] = {
|
||||
[MOUSE_CLICK_DOWN] = "Mouse1",
|
||||
[MOUSE_CLICK_UP] = "!Mouse1",
|
||||
[MOUSE_DCLICK_DOWN] = "MouseD1",
|
||||
[MOUSE_DCLICK_UP] = "!MouseD1",
|
||||
};
|
||||
|
||||
void setup_abe ( void )
|
||||
{
|
||||
for ( int iter = 0; iter < NUM_ABE; iter++ ) {
|
||||
int id = bindings[iter].id;
|
||||
// set pointer to name.
|
||||
abe[id].name = bindings[iter].name;
|
||||
abe[id].keystr = g_strdup ( bindings[iter].keybinding );
|
||||
abe[id].num_bindings = 0;
|
||||
abe[id].kb = NULL;
|
||||
|
||||
config_parser_add_option ( xrm_String, abe[id].name, (void * *) &( abe[id].keystr ), bindings[iter].comment );
|
||||
for ( gsize i = 0; i < G_N_ELEMENTS ( rofi_bindings ); ++i ) {
|
||||
ActionBindingEntry *b = &rofi_bindings[i];
|
||||
b->binding = g_strdup ( b->binding );
|
||||
config_parser_add_option ( xrm_String, b->name, (void * *) &( b->binding ), b->comment );
|
||||
}
|
||||
}
|
||||
|
||||
gboolean parse_keys_abe ( void )
|
||||
gboolean parse_keys_abe ( NkBindings *bindings )
|
||||
{
|
||||
GError *error = NULL;
|
||||
GString *error_msg = g_string_new ( "" );
|
||||
for ( int iter = 0; iter < NUM_ABE; iter++ ) {
|
||||
char *keystr = g_strdup ( abe[iter].keystr );
|
||||
char *sp = NULL;
|
||||
|
||||
g_free ( abe[iter].kb );
|
||||
abe[iter].kb = NULL;
|
||||
abe[iter].num_bindings = 0;
|
||||
for ( gsize i = 0; i < G_N_ELEMENTS ( rofi_bindings ); ++i ) {
|
||||
ActionBindingEntry *b = &rofi_bindings[i];
|
||||
char *keystr = g_strdup ( b->binding );
|
||||
char *sp = NULL;
|
||||
|
||||
// Iter over bindings.
|
||||
const char *const sep = ",";
|
||||
for ( char *entry = strtok_r ( keystr, sep, &sp ); entry != NULL; entry = strtok_r ( NULL, sep, &sp ) ) {
|
||||
abe[iter].kb = g_realloc ( abe[iter].kb, ( abe[iter].num_bindings + 1 ) * sizeof ( KeyBinding ) );
|
||||
KeyBinding *kb = &( abe[iter].kb[abe[iter].num_bindings] );
|
||||
memset ( kb, 0, sizeof ( KeyBinding ) );
|
||||
if ( x11_parse_key ( entry, &( kb->modmask ), &( kb->keysym ), &( kb->release ), error_msg ) ) {
|
||||
abe[iter].num_bindings++;
|
||||
}
|
||||
else {
|
||||
char *name = g_markup_escape_text ( abe[iter].name, -1 );
|
||||
g_string_append_printf ( error_msg, "Failed to set binding for: <b>%s</b>\n\n", name );
|
||||
g_free ( name );
|
||||
if ( !nk_bindings_add_binding ( bindings, b->scope, entry, rofi_view_trigger_action, GUINT_TO_POINTER ( b->id ), NULL, &error ) ) {
|
||||
g_string_append_c ( g_string_append ( error_msg, error->message ), '\n' );
|
||||
g_clear_error ( &error );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,67 +168,13 @@ gboolean parse_keys_abe ( void )
|
|||
g_string_free ( error_msg, TRUE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for ( gsize i = SCOPE_MIN_FIXED; i <= SCOPE_MAX_FIXED; ++i ) {
|
||||
for ( gsize j = 1; j < G_N_ELEMENTS ( mouse_default_bindings ); ++j ) {
|
||||
nk_bindings_add_binding ( bindings, i, mouse_default_bindings[j], rofi_view_trigger_action, GSIZE_TO_POINTER ( j ), NULL, NULL );
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free ( error_msg, TRUE );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void cleanup_abe ( void )
|
||||
{
|
||||
for ( int iter = 0; iter < NUM_ABE; iter++ ) {
|
||||
g_free ( abe[iter].kb );
|
||||
abe[iter].kb = NULL;
|
||||
abe[iter].num_bindings = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array holding actions that should be trigger on release.
|
||||
*/
|
||||
static gboolean _abe_trigger_on_release[NUM_ABE] = { 0 };
|
||||
|
||||
static gboolean abe_test_action ( KeyBindingAction action, unsigned int mask, xkb_keysym_t key )
|
||||
{
|
||||
ActionBindingEntry *akb = &( abe[action] );
|
||||
|
||||
for ( int iter = 0; iter < akb->num_bindings; iter++ ) {
|
||||
const KeyBinding * const kb = &( akb->kb[iter] );
|
||||
if ( ( kb->keysym == key ) && ( kb->modmask == mask ) ) {
|
||||
if ( kb->release ) {
|
||||
_abe_trigger_on_release[action] = TRUE;
|
||||
}
|
||||
else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
KeyBindingAction abe_find_action ( unsigned int mask, xkb_keysym_t key )
|
||||
{
|
||||
KeyBindingAction action;
|
||||
|
||||
for ( action = 0; action < NUM_ABE; ++action ) {
|
||||
if ( abe_test_action ( action, mask, key ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
void abe_trigger_release ( void )
|
||||
{
|
||||
RofiViewState *state;
|
||||
|
||||
state = rofi_view_get_active ( );
|
||||
if ( state ) {
|
||||
for ( KeyBindingAction action = 0; action < NUM_ABE; ++action ) {
|
||||
if ( _abe_trigger_on_release[action] ) {
|
||||
rofi_view_trigger_action ( state, action );
|
||||
_abe_trigger_on_release[action] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
103
source/rofi.c
103
source/rofi.c
|
@ -43,7 +43,6 @@
|
|||
#include <xcb/xcb_ewmh.h>
|
||||
#include <xcb/xkb.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -91,19 +90,13 @@ void rofi_add_error_message ( GString *str )
|
|||
/** global structure holding the keyboard status */
|
||||
struct xkb_stuff xkb = {
|
||||
.xcb_connection = NULL,
|
||||
.context = NULL,
|
||||
.keymap = NULL,
|
||||
.state = NULL,
|
||||
.compose = {
|
||||
.table = NULL,
|
||||
.state = NULL
|
||||
}
|
||||
.bindings = NULL,
|
||||
};
|
||||
|
||||
/** Path to the configuration file */
|
||||
G_MODULE_EXPORT char *config_path = NULL;
|
||||
/** Array holding all activated modi. */
|
||||
Mode **modi = NULL;
|
||||
Mode **modi = NULL;
|
||||
|
||||
/** List of (possibly uninitialized) modi's */
|
||||
Mode ** available_modi = NULL;
|
||||
|
@ -441,26 +434,7 @@ static void cleanup ()
|
|||
}
|
||||
// XKB Cleanup
|
||||
//
|
||||
if ( xkb.compose.state != NULL ) {
|
||||
xkb_compose_state_unref ( xkb.compose.state );
|
||||
xkb.compose.state = NULL;
|
||||
}
|
||||
if ( xkb.compose.table != NULL ) {
|
||||
xkb_compose_table_unref ( xkb.compose.table );
|
||||
xkb.compose.table = NULL;
|
||||
}
|
||||
if ( xkb.state != NULL ) {
|
||||
xkb_state_unref ( xkb.state );
|
||||
xkb.state = NULL;
|
||||
}
|
||||
if ( xkb.keymap != NULL ) {
|
||||
xkb_keymap_unref ( xkb.keymap );
|
||||
xkb.keymap = NULL;
|
||||
}
|
||||
if ( xkb.context != NULL ) {
|
||||
xkb_context_unref ( xkb.context );
|
||||
xkb.context = NULL;
|
||||
}
|
||||
nk_bindings_free ( xkb.bindings );
|
||||
|
||||
// Cleanup
|
||||
xcb_stuff_wipe ( xcb );
|
||||
|
@ -472,9 +446,6 @@ static void cleanup ()
|
|||
}
|
||||
g_free ( modi );
|
||||
|
||||
// Cleanup the custom keybinding
|
||||
cleanup_abe ();
|
||||
|
||||
g_free ( config_path );
|
||||
|
||||
if ( list_of_error_msgs ) {
|
||||
|
@ -558,8 +529,9 @@ static void rofi_collect_modi_dir ( const char *base_dir )
|
|||
g_warning ( "Symbol 'mode' not found in module: %s", dn );
|
||||
g_module_close ( mod );
|
||||
}
|
||||
} else {
|
||||
g_warning ( "Failed to open 'mode' plugin: '%s', error: %s", dn, g_module_error());
|
||||
}
|
||||
else {
|
||||
g_warning ( "Failed to open 'mode' plugin: '%s', error: %s", dn, g_module_error () );
|
||||
}
|
||||
g_free ( fn );
|
||||
}
|
||||
|
@ -694,32 +666,27 @@ static gboolean main_loop_x11_event_handler ( xcb_generic_event_t *ev, G_GNUC_UN
|
|||
switch ( ev->pad0 )
|
||||
{
|
||||
case XCB_XKB_MAP_NOTIFY:
|
||||
xkb_state_unref ( xkb.state );
|
||||
xkb_keymap_unref ( xkb.keymap );
|
||||
xkb.keymap = xkb_x11_keymap_new_from_device ( xkb.context, xcb->connection, xkb.device_id, 0 );
|
||||
xkb.state = xkb_x11_state_new_from_device ( xkb.keymap, xcb->connection, xkb.device_id );
|
||||
{
|
||||
struct xkb_keymap *keymap = xkb_x11_keymap_new_from_device ( nk_bindings_get_context ( xkb.bindings ), xcb->connection, xkb.device_id, 0 );
|
||||
struct xkb_state *state = xkb_x11_state_new_from_device ( keymap, xcb->connection, xkb.device_id );
|
||||
nk_bindings_update_keymap ( xkb.bindings, keymap, state );
|
||||
xkb_keymap_unref ( keymap );
|
||||
xkb_state_unref ( state );
|
||||
break;
|
||||
}
|
||||
case XCB_XKB_STATE_NOTIFY:
|
||||
{
|
||||
xcb_xkb_state_notify_event_t *ksne = (xcb_xkb_state_notify_event_t *) ev;
|
||||
guint modmask;
|
||||
xkb_state_update_mask ( xkb.state,
|
||||
ksne->baseMods,
|
||||
ksne->latchedMods,
|
||||
ksne->lockedMods,
|
||||
ksne->baseGroup,
|
||||
ksne->latchedGroup,
|
||||
ksne->lockedGroup );
|
||||
modmask = x11_get_current_mask ( &xkb );
|
||||
if ( modmask == 0 ) {
|
||||
abe_trigger_release ( );
|
||||
|
||||
// Because of abe_trigger, state of rofi can be changed. handle this!
|
||||
// Run mainloop on dummy event.
|
||||
xcb_generic_event_t dev;
|
||||
dev.response_type = 0;
|
||||
main_loop_x11_event_handler_view ( &dev );
|
||||
}
|
||||
nk_bindings_update_mask ( xkb.bindings,
|
||||
ksne->baseMods,
|
||||
ksne->latchedMods,
|
||||
ksne->lockedMods,
|
||||
ksne->baseGroup,
|
||||
ksne->latchedGroup,
|
||||
ksne->lockedGroup );
|
||||
xcb_generic_event_t dev;
|
||||
dev.response_type = 0;
|
||||
main_loop_x11_event_handler_view ( &dev );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -830,7 +797,7 @@ static gboolean startup ( G_GNUC_UNUSED gpointer data )
|
|||
__create_window ( window_flags );
|
||||
TICK_N ( "Create Window" );
|
||||
// Parse the keybindings.
|
||||
if ( !parse_keys_abe () ) {
|
||||
if ( !parse_keys_abe ( xkb.bindings ) ) {
|
||||
// Error dialog
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
@ -1032,8 +999,8 @@ int main ( int argc, char *argv[] )
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
xkb.context = xkb_context_new ( XKB_CONTEXT_NO_FLAGS );
|
||||
if ( xkb.context == NULL ) {
|
||||
struct xkb_context *xkb_context = xkb_context_new ( XKB_CONTEXT_NO_FLAGS );
|
||||
if ( xkb_context == NULL ) {
|
||||
g_warning ( "cannot create XKB context!" );
|
||||
cleanup ();
|
||||
return EXIT_FAILURE;
|
||||
|
@ -1083,33 +1050,27 @@ int main ( int argc, char *argv[] )
|
|||
required_map_parts, /* map */
|
||||
&details );
|
||||
|
||||
xkb.keymap = xkb_x11_keymap_new_from_device ( xkb.context, xcb->connection, xkb.device_id, XKB_KEYMAP_COMPILE_NO_FLAGS );
|
||||
if ( xkb.keymap == NULL ) {
|
||||
struct xkb_keymap *keymap = xkb_x11_keymap_new_from_device ( xkb_context, xcb->connection, xkb.device_id, XKB_KEYMAP_COMPILE_NO_FLAGS );
|
||||
if ( keymap == NULL ) {
|
||||
g_warning ( "Failed to get Keymap for current keyboard device." );
|
||||
cleanup ();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
xkb.state = xkb_x11_state_new_from_device ( xkb.keymap, xcb->connection, xkb.device_id );
|
||||
if ( xkb.state == NULL ) {
|
||||
struct xkb_state *state = xkb_x11_state_new_from_device ( keymap, xcb->connection, xkb.device_id );
|
||||
if ( state == NULL ) {
|
||||
g_warning ( "Failed to get state object for current keyboard device." );
|
||||
cleanup ();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
xkb.compose.table = xkb_compose_table_new_from_locale ( xkb.context, setlocale ( LC_CTYPE, NULL ), 0 );
|
||||
if ( xkb.compose.table != NULL ) {
|
||||
xkb.compose.state = xkb_compose_state_new ( xkb.compose.table, 0 );
|
||||
}
|
||||
else {
|
||||
g_warning ( "Failed to get keyboard compose table. Trying to limp on." );
|
||||
}
|
||||
xkb.bindings = nk_bindings_new ( xkb_context, keymap, state );
|
||||
|
||||
if ( xcb_connection_has_error ( xcb->connection ) ) {
|
||||
g_warning ( "Connection has error" );
|
||||
cleanup ();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
x11_setup ( &xkb );
|
||||
x11_setup ();
|
||||
TICK_N ( "Setup xkb" );
|
||||
if ( xcb_connection_has_error ( xcb->connection ) ) {
|
||||
g_warning ( "Connection has error" );
|
||||
|
|
193
source/view.c
193
source/view.c
|
@ -69,10 +69,6 @@
|
|||
|
||||
#include "xcb.h"
|
||||
|
||||
#ifdef XkBCOMMON_HAS_CONSUMED2
|
||||
#define xkb_state_key_get_consumed_mods( s, k ) xkb_state_key_get_consumed_mods2 ( s, k, XKB_CONSUMED_MODE_GTK )
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @param state The handle to the view
|
||||
* @param qr Indicate if queue_redraw should be called on changes.
|
||||
|
@ -1008,31 +1004,6 @@ static void rofi_view_paste ( RofiViewState *state, xcb_selection_notify_event_t
|
|||
}
|
||||
}
|
||||
|
||||
static void rofi_view_mouse_navigation ( RofiViewState *state, xcb_button_press_event_t *xbe )
|
||||
{
|
||||
// Scroll event
|
||||
if ( xbe->detail > 3 ) {
|
||||
if ( xbe->detail == 4 ) {
|
||||
listview_nav_up ( state->list_view );
|
||||
}
|
||||
else if ( xbe->detail == 5 ) {
|
||||
listview_nav_down ( state->list_view );
|
||||
}
|
||||
else if ( xbe->detail == 6 ) {
|
||||
listview_nav_left ( state->list_view );
|
||||
}
|
||||
else if ( xbe->detail == 7 ) {
|
||||
listview_nav_right ( state->list_view );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
xcb_button_press_event_t rel = *xbe;
|
||||
if ( widget_clicked ( WIDGET ( state->main_window ), &rel ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void _rofi_view_reload_row ( RofiViewState *state )
|
||||
{
|
||||
g_free ( state->line_map );
|
||||
|
@ -1152,9 +1123,9 @@ void rofi_view_finalize ( RofiViewState *state )
|
|||
}
|
||||
}
|
||||
|
||||
gboolean rofi_view_trigger_action ( RofiViewState *state, KeyBindingAction action )
|
||||
static void rofi_view_trigger_global_action ( KeyBindingAction action )
|
||||
{
|
||||
gboolean ret = TRUE;
|
||||
RofiViewState *state = rofi_view_get_active ();
|
||||
switch ( action )
|
||||
{
|
||||
// Handling of paste
|
||||
|
@ -1207,9 +1178,6 @@ gboolean rofi_view_trigger_action ( RofiViewState *state, KeyBindingAction actio
|
|||
state->retv = MENU_ENTRY_DELETE;
|
||||
state->quit = TRUE;
|
||||
}
|
||||
else {
|
||||
ret = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SELECT_ELEMENT_1:
|
||||
|
@ -1372,65 +1340,34 @@ gboolean rofi_view_trigger_action ( RofiViewState *state, KeyBindingAction actio
|
|||
state->quit = TRUE;
|
||||
break;
|
||||
}
|
||||
case NUM_ABE:
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rofi_view_handle_keypress ( RofiViewState *state, xkb_stuff *xkb, xcb_key_press_event_t *xkpe )
|
||||
gboolean rofi_view_trigger_action ( guint scope, gpointer user_data )
|
||||
{
|
||||
xcb_keysym_t key;
|
||||
char pad[32];
|
||||
int len = 0;
|
||||
|
||||
key = xkb_state_key_get_one_sym ( xkb->state, xkpe->detail );
|
||||
|
||||
if ( xkb->compose.state != NULL ) {
|
||||
if ( ( key != XKB_KEY_NoSymbol ) && ( xkb_compose_state_feed ( xkb->compose.state, key ) == XKB_COMPOSE_FEED_ACCEPTED ) ) {
|
||||
switch ( xkb_compose_state_get_status ( xkb->compose.state ) )
|
||||
{
|
||||
case XKB_COMPOSE_CANCELLED:
|
||||
/* Eat the keysym that cancelled the compose sequence.
|
||||
* This is default behaviour with Xlib */
|
||||
case XKB_COMPOSE_COMPOSING:
|
||||
key = XKB_KEY_NoSymbol;
|
||||
break;
|
||||
case XKB_COMPOSE_COMPOSED:
|
||||
key = xkb_compose_state_get_one_sym ( xkb->compose.state );
|
||||
len = xkb_compose_state_get_utf8 ( xkb->compose.state, pad, sizeof ( pad ) );
|
||||
break;
|
||||
case XKB_COMPOSE_NOTHING:
|
||||
break;
|
||||
}
|
||||
if ( ( key == XKB_KEY_NoSymbol ) && ( len == 0 ) ) {
|
||||
return;
|
||||
}
|
||||
RofiViewState *state = rofi_view_get_active ();
|
||||
g_print ( "TRY ACTION scope %u\n", scope );
|
||||
switch ( (BindingsScope) scope )
|
||||
{
|
||||
case SCOPE_GLOBAL:
|
||||
rofi_view_trigger_global_action ( GPOINTER_TO_UINT ( user_data ) );
|
||||
return TRUE;
|
||||
case SCOPE_MOUSE_LISTVIEW:
|
||||
case SCOPE_MOUSE_LISTVIEW_ELEMENT:
|
||||
case SCOPE_MOUSE_EDITBOX:
|
||||
case SCOPE_MOUSE_SCROLLBAR:
|
||||
case SCOPE_MOUSE_SIDEBAR_MODI:
|
||||
{
|
||||
gint x = state->mouse.x, y = state->mouse.y;
|
||||
widget *target = widget_find_mouse_target ( WIDGET ( state->main_window ), scope, &x, &y );
|
||||
if ( target == NULL ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return widget_trigger_action ( target, GPOINTER_TO_UINT ( user_data ), x, y );
|
||||
}
|
||||
|
||||
if ( len == 0 ) {
|
||||
len = xkb_state_key_get_utf8 ( xkb->state, xkpe->detail, pad, sizeof ( pad ) );
|
||||
}
|
||||
|
||||
xkb_mod_mask_t consumed = xkb_state_key_get_consumed_mods ( xkb->state, xkpe->detail );
|
||||
|
||||
unsigned int modstate = x11_canonalize_mask ( xkpe->state & ( ~consumed ) );
|
||||
|
||||
if ( key != XKB_KEY_NoSymbol ) {
|
||||
KeyBindingAction action;
|
||||
action = abe_find_action ( modstate, key );
|
||||
if ( rofi_view_trigger_action ( state, action ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( len > 0 ) && ( textbox_append_char ( state->text, pad, len ) ) ) {
|
||||
state->refilter = TRUE;
|
||||
return;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb_stuff *xkb )
|
||||
|
@ -1472,18 +1409,27 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb
|
|||
state->mouse_seen = TRUE;
|
||||
}
|
||||
xcb_motion_notify_event_t xme = *( (xcb_motion_notify_event_t *) event );
|
||||
state->mouse.x = xme.event_x;
|
||||
state->mouse.y = xme.event_y;
|
||||
if ( widget_motion_notify ( WIDGET ( state->main_window ), &xme ) ) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_BUTTON_PRESS:
|
||||
rofi_view_mouse_navigation ( state, (xcb_button_press_event_t *) event );
|
||||
{
|
||||
xcb_button_press_event_t *bpe = (xcb_button_press_event_t *) event;
|
||||
state->mouse.x = bpe->event_x;
|
||||
state->mouse.y = bpe->event_y;
|
||||
nk_bindings_handle_button ( xkb->bindings, bpe->detail, NK_BINDINGS_BUTTON_STATE_PRESS, bpe->time );
|
||||
break;
|
||||
}
|
||||
case XCB_BUTTON_RELEASE:
|
||||
{
|
||||
xcb_button_release_event_t *bre = (xcb_button_release_event_t *) event;
|
||||
nk_bindings_handle_button ( xkb->bindings, bre->detail, NK_BINDINGS_BUTTON_STATE_RELEASE, bre->time );
|
||||
if ( config.click_to_exit == TRUE ) {
|
||||
if ( ( CacheState.flags & MENU_NORMAL_WINDOW ) == 0 ) {
|
||||
xcb_button_release_event_t *bre = (xcb_button_release_event_t *) event;
|
||||
if ( ( state->mouse_seen == FALSE ) && ( bre->event != CacheState.main_window ) ) {
|
||||
state->quit = TRUE;
|
||||
state->retv = MENU_CANCEL;
|
||||
|
@ -1492,35 +1438,39 @@ void rofi_view_itterrate ( RofiViewState *state, xcb_generic_event_t *event, xkb
|
|||
state->mouse_seen = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Paste event.
|
||||
case XCB_SELECTION_NOTIFY:
|
||||
rofi_view_paste ( state, (xcb_selection_notify_event_t *) event );
|
||||
break;
|
||||
case XCB_KEYMAP_NOTIFY:
|
||||
{
|
||||
xcb_keymap_notify_event_t *kne = (xcb_keymap_notify_event_t *) event;
|
||||
guint modstate = x11_get_current_mask ( xkb );
|
||||
xcb_keymap_notify_event_t *kne = (xcb_keymap_notify_event_t *) event;
|
||||
for ( gint32 by = 0; by < 31; ++by ) {
|
||||
for ( gint8 bi = 0; bi < 7; ++bi ) {
|
||||
if ( kne->keys[by] & ( 1 << bi ) ) {
|
||||
// X11 keycodes starts at 8
|
||||
xkb_keysym_t key = xkb_state_key_get_one_sym ( xkb->state, ( 8 * by + bi ) + 8 );
|
||||
abe_find_action ( modstate, key );
|
||||
nk_bindings_handle_key ( xkb->bindings, ( 8 * by + bi ) + 8, NK_BINDINGS_KEY_STATE_PRESSED );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_KEY_PRESS:
|
||||
rofi_view_handle_keypress ( state, xkb, (xcb_key_press_event_t *) event );
|
||||
{
|
||||
xcb_key_press_event_t *xkpe = (xcb_key_press_event_t *) event;
|
||||
gchar *text;
|
||||
|
||||
text = nk_bindings_handle_key ( xkb->bindings, xkpe->detail, NK_BINDINGS_KEY_STATE_PRESS );
|
||||
if ( ( text != NULL ) && ( textbox_append_char ( state->text, text, strlen ( text ) ) ) ) {
|
||||
state->refilter = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_KEY_RELEASE:
|
||||
{
|
||||
xcb_key_release_event_t *xkre = (xcb_key_release_event_t *) event;
|
||||
unsigned int modstate = x11_canonalize_mask ( xkre->state );
|
||||
if ( modstate == 0 ) {
|
||||
abe_trigger_release ( );
|
||||
}
|
||||
xcb_key_release_event_t *xkre = (xcb_key_release_event_t *) event;
|
||||
nk_bindings_handle_key ( xkb->bindings, xkre->detail, NK_BINDINGS_KEY_STATE_RELEASE );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1550,26 +1500,41 @@ static int rofi_view_calculate_height ( RofiViewState *state )
|
|||
return height;
|
||||
}
|
||||
|
||||
static gboolean rofi_view_modi_clicked_cb ( widget *textbox, G_GNUC_UNUSED xcb_button_press_event_t *xbe, void *udata )
|
||||
static gboolean textbox_sidebar_modi_trigger_action ( widget *wid, MouseBindingMouseDefaultAction action, gint x, gint y, G_GNUC_UNUSED void *user_data )
|
||||
{
|
||||
RofiViewState *state = ( RofiViewState *) udata;
|
||||
for ( unsigned int i = 0; i < state->num_modi; i++ ) {
|
||||
if ( WIDGET ( state->modi[i] ) == textbox ) {
|
||||
state->retv = MENU_QUICK_SWITCH | ( i & MENU_LOWER_MASK );
|
||||
state->quit = TRUE;
|
||||
state->skip_absorb = TRUE;
|
||||
return TRUE;
|
||||
g_print ( "CLICK ON SIDEBAR\n" );
|
||||
RofiViewState *state = ( RofiViewState *) user_data;
|
||||
unsigned int i;
|
||||
for ( i = 0; i < state->num_modi; i++ ) {
|
||||
if ( WIDGET ( state->modi[i] ) == wid ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == state->num_modi ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch ( action )
|
||||
{
|
||||
case MOUSE_CLICK_DOWN:
|
||||
state->retv = MENU_QUICK_SWITCH | ( i & MENU_LOWER_MASK );
|
||||
state->quit = TRUE;
|
||||
state->skip_absorb = TRUE;
|
||||
return TRUE;
|
||||
case MOUSE_CLICK_UP:
|
||||
case MOUSE_DCLICK_DOWN:
|
||||
case MOUSE_DCLICK_UP:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// @TODO don't like this construction.
|
||||
static void rofi_view_listview_mouse_activated_cb ( listview *lv, xcb_button_press_event_t *xce, void *udata )
|
||||
static void rofi_view_listview_mouse_activated_cb ( listview *lv, gboolean custom, void *udata )
|
||||
{
|
||||
RofiViewState *state = (RofiViewState *) udata;
|
||||
int control = x11_modifier_active ( xce->state, X11MOD_CONTROL );
|
||||
RofiViewState *state = (RofiViewState *) udata;
|
||||
state->retv = MENU_OK;
|
||||
if ( control ) {
|
||||
if ( custom ) {
|
||||
state->retv |= MENU_CUSTOM_ACTION;
|
||||
}
|
||||
( state->selected_line ) = state->line_map[listview_get_selected ( lv )];
|
||||
|
@ -1619,10 +1584,10 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
state->modi = g_malloc0 ( state->num_modi * sizeof ( textbox * ) );
|
||||
for ( unsigned int j = 0; j < state->num_modi; j++ ) {
|
||||
const Mode * mode = rofi_get_mode ( j );
|
||||
state->modi[j] = textbox_create ( "window.mainbox.sidebar.button", TB_CENTER | TB_AUTOHEIGHT, ( mode == state->sw ) ? HIGHLIGHT : NORMAL,
|
||||
mode_get_display_name ( mode ) );
|
||||
state->modi[j] = textbox_create_full ( WIDGET_TYPE_SIDEBAR_MODI, "window.mainbox.sidebar.button", TB_CENTER | TB_AUTOHEIGHT, ( mode == state->sw ) ? HIGHLIGHT : NORMAL,
|
||||
mode_get_display_name ( mode ) );
|
||||
box_add ( state->sidebar_bar, WIDGET ( state->modi[j] ), TRUE, j );
|
||||
widget_set_clicked_handler ( WIDGET ( state->modi[j] ), rofi_view_modi_clicked_cb, state );
|
||||
widget_set_trigger_action_handler ( WIDGET ( state->modi[j] ), textbox_sidebar_modi_trigger_action, state );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1642,7 +1607,7 @@ RofiViewState *rofi_view_create ( Mode *sw,
|
|||
// Entry box
|
||||
TextboxFlags tfl = TB_EDITABLE;
|
||||
tfl |= ( ( menu_flags & MENU_PASSWORD ) == MENU_PASSWORD ) ? TB_PASSWORD : 0;
|
||||
state->text = textbox_create ( "window.mainbox.inputbar.entry", tfl | TB_AUTOHEIGHT, NORMAL, input );
|
||||
state->text = textbox_create_full ( WIDGET_TYPE_EDITBOX, "window.mainbox.inputbar.entry", tfl | TB_AUTOHEIGHT, NORMAL, input );
|
||||
|
||||
box_add ( state->input_bar, WIDGET ( state->text ), TRUE, 2 );
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ static void box_resize ( widget *widget, short w, short h )
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean box_clicked ( widget *wid, xcb_button_press_event_t *xbe, G_GNUC_UNUSED void *udata )
|
||||
static widget *box_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
|
||||
{
|
||||
box *b = (box *) wid;
|
||||
for ( GList *iter = g_list_first ( b->children ); iter != NULL; iter = g_list_next ( iter ) ) {
|
||||
|
@ -285,15 +285,20 @@ static gboolean box_clicked ( widget *wid, xcb_button_press_event_t *xbe, G_GNUC
|
|||
if ( !child->enabled ) {
|
||||
continue;
|
||||
}
|
||||
if ( widget_intersect ( child, xbe->event_x, xbe->event_y ) ) {
|
||||
xcb_button_press_event_t rel = *xbe;
|
||||
rel.event_x -= child->x;
|
||||
rel.event_y -= child->y;
|
||||
return widget_clicked ( child, &rel );
|
||||
if ( widget_intersect ( child, *x, *y ) ) {
|
||||
gint rx = *x - child->x;
|
||||
gint ry = *y - child->y;
|
||||
widget *target = widget_find_mouse_target ( child, type, &rx, &ry );
|
||||
if ( target != NULL ) {
|
||||
*x = rx;
|
||||
*y = ry;
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean box_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
box *b = (box *) wid;
|
||||
|
@ -316,13 +321,13 @@ box * box_create ( const char *name, boxType type )
|
|||
{
|
||||
box *b = g_malloc0 ( sizeof ( box ) );
|
||||
// Initialize widget.
|
||||
widget_init ( WIDGET ( b ), name );
|
||||
widget_init ( WIDGET ( b ), WIDGET_TYPE_UNKNOWN, name );
|
||||
b->type = type;
|
||||
b->widget.draw = box_draw;
|
||||
b->widget.free = box_free;
|
||||
b->widget.resize = box_resize;
|
||||
b->widget.update = box_update;
|
||||
b->widget.clicked = box_clicked;
|
||||
b->widget.find_mouse_target = box_find_mouse_target;
|
||||
b->widget.motion_notify = box_motion_notify;
|
||||
b->widget.get_desired_height = box_get_desired_height;
|
||||
b->widget.enabled = rofi_theme_get_boolean ( WIDGET ( b ), "enabled", TRUE );
|
||||
|
|
|
@ -88,16 +88,23 @@ static void container_resize ( widget *widget, short w, short h )
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean container_clicked ( widget *wid, xcb_button_press_event_t *xbe, G_GNUC_UNUSED void *udata )
|
||||
static widget *container_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
|
||||
{
|
||||
container *b = (container *) wid;
|
||||
if ( widget_intersect ( b->child, xbe->event_x, xbe->event_y ) ) {
|
||||
xcb_button_press_event_t rel = *xbe;
|
||||
rel.event_x -= b->child->x;
|
||||
rel.event_y -= b->child->y;
|
||||
return widget_clicked ( b->child, &rel );
|
||||
if ( !widget_intersect ( b->child, *x, *y ) ) {
|
||||
return NULL;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
gint rx = *x - b->child->x;
|
||||
gint ry = *y - b->child->y;
|
||||
widget *target = widget_find_mouse_target ( b->child, type, &rx, &ry );
|
||||
if ( target == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*x = rx;
|
||||
*y = ry;
|
||||
return target;
|
||||
}
|
||||
static gboolean container_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
|
@ -115,12 +122,12 @@ container * container_create ( const char *name )
|
|||
{
|
||||
container *b = g_malloc0 ( sizeof ( container ) );
|
||||
// Initialize widget.
|
||||
widget_init ( WIDGET ( b ), name );
|
||||
widget_init ( WIDGET ( b ), WIDGET_TYPE_UNKNOWN, name );
|
||||
b->widget.draw = container_draw;
|
||||
b->widget.free = container_free;
|
||||
b->widget.resize = container_resize;
|
||||
b->widget.update = container_update;
|
||||
b->widget.clicked = container_clicked;
|
||||
b->widget.find_mouse_target = container_find_mouse_target;
|
||||
b->widget.motion_notify = container_motion_notify;
|
||||
b->widget.get_desired_height = container_get_desired_height;
|
||||
b->widget.enabled = rofi_theme_get_boolean ( WIDGET ( b ), "enabled", TRUE );
|
||||
|
|
|
@ -78,8 +78,6 @@ struct _listview
|
|||
listview_update_callback callback;
|
||||
void *udata;
|
||||
|
||||
gboolean scrollbar_scroll;
|
||||
|
||||
xcb_timestamp_t last_click;
|
||||
listview_mouse_activated_cb mouse_activated;
|
||||
void *mouse_activated_data;
|
||||
|
@ -221,6 +219,8 @@ static void listview_draw ( widget *wid, cairo_t *draw )
|
|||
widget_draw ( WIDGET ( lv->scrollbar ), draw );
|
||||
}
|
||||
|
||||
static gboolean listview_element_trigger_action ( widget *wid, MouseBindingListviewElementAction action, gint x, gint y, void *user_data );
|
||||
|
||||
static void listview_recompute_elements ( listview *lv )
|
||||
{
|
||||
unsigned int newne = 0;
|
||||
|
@ -243,7 +243,8 @@ static void listview_recompute_elements ( listview *lv )
|
|||
char *name = g_strjoin ( ".", lv->listview_name, "element", NULL );
|
||||
for ( unsigned int i = lv->cur_elements; i < newne; i++ ) {
|
||||
TextboxFlags flags = ( lv->multi_select ) ? TB_INDICATOR : 0;
|
||||
lv->boxes[i] = textbox_create ( name, flags, NORMAL, "" );
|
||||
lv->boxes[i] = textbox_create_full ( WIDGET_TYPE_LISTVIEW_ELEMENT, name, flags, NORMAL, "" );
|
||||
widget_set_trigger_action_handler ( WIDGET ( lv->boxes[i] ), listview_element_trigger_action, lv );
|
||||
}
|
||||
g_free ( name );
|
||||
}
|
||||
|
@ -301,74 +302,97 @@ static void listview_resize ( widget *wid, short w, short h )
|
|||
widget_queue_redraw ( wid );
|
||||
}
|
||||
|
||||
static gboolean listview_scrollbar_clicked ( widget *sb, xcb_button_press_event_t * xce, void *udata )
|
||||
static widget *listview_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
|
||||
{
|
||||
listview *lv = (listview *) udata;
|
||||
widget *target = NULL;
|
||||
gint rx, ry;
|
||||
listview *lv = (listview *) wid;
|
||||
if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) && widget_intersect ( WIDGET ( lv->scrollbar ), *x, *y ) ) {
|
||||
rx = *x - widget_get_x_pos ( WIDGET ( lv->scrollbar ) );
|
||||
ry = *y - widget_get_y_pos ( WIDGET ( lv->scrollbar ) );
|
||||
target = widget_find_mouse_target ( WIDGET ( lv->scrollbar ), type, &rx, &ry );
|
||||
}
|
||||
|
||||
unsigned int sel = scrollbar_clicked ( (scrollbar *) sb, xce->event_y );
|
||||
listview_set_selected ( lv, sel );
|
||||
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
|
||||
unsigned int i;
|
||||
for ( i = 0; i < max && target == NULL; i++ ) {
|
||||
widget *w = WIDGET ( lv->boxes[i] );
|
||||
if ( widget_intersect ( w, *x, *y ) ) {
|
||||
rx = *x - widget_get_x_pos ( w );
|
||||
ry = *y - widget_get_y_pos ( w );
|
||||
target = widget_find_mouse_target ( w, type, &rx, &ry );
|
||||
}
|
||||
}
|
||||
|
||||
if ( target != NULL ) {
|
||||
*x = rx;
|
||||
*y = ry;
|
||||
return target;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean listview_trigger_action ( widget *wid, MouseBindingListviewAction action, G_GNUC_UNUSED gint x, G_GNUC_UNUSED gint y, G_GNUC_UNUSED void *user_data )
|
||||
{
|
||||
listview *lv = (listview *) wid;
|
||||
switch ( action )
|
||||
{
|
||||
case SCROLL_LEFT:
|
||||
listview_nav_left ( lv );
|
||||
break;
|
||||
case SCROLL_RIGHT:
|
||||
listview_nav_right ( lv );
|
||||
break;
|
||||
case SCROLL_DOWN:
|
||||
listview_nav_down ( lv );
|
||||
break;
|
||||
case SCROLL_UP:
|
||||
listview_nav_up ( lv );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean listview_clicked ( widget *wid, xcb_button_press_event_t *xce, G_GNUC_UNUSED void *udata )
|
||||
static gboolean listview_element_trigger_action ( widget *wid, MouseBindingListviewElementAction action, gint x, gint y, void *user_data )
|
||||
{
|
||||
listview *lv = (listview *) wid;
|
||||
lv->scrollbar_scroll = FALSE;
|
||||
if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) && widget_intersect ( WIDGET ( lv->scrollbar ), xce->event_x, xce->event_y ) ) {
|
||||
// Forward to handler of scrollbar.
|
||||
xcb_button_press_event_t xce2 = *xce;
|
||||
xce->event_x -= widget_get_x_pos ( WIDGET ( lv->scrollbar ) );
|
||||
xce->event_y -= widget_get_y_pos ( WIDGET ( lv->scrollbar ) );
|
||||
lv->scrollbar_scroll = TRUE;
|
||||
return widget_clicked ( WIDGET ( lv->scrollbar ), &xce2 );
|
||||
}
|
||||
// Handle the boxes.
|
||||
listview *lv = (listview *) user_data;
|
||||
unsigned int max = MIN ( lv->cur_elements, lv->req_elements - lv->last_offset );
|
||||
for ( unsigned int i = 0; i < max; i++ ) {
|
||||
widget *w = WIDGET ( lv->boxes[i] );
|
||||
if ( widget_intersect ( w, xce->event_x, xce->event_y ) ) {
|
||||
if ( ( lv->last_offset + i ) == lv->selected ) {
|
||||
if ( ( xce->time - lv->last_click ) < 200 ) {
|
||||
// Somehow signal we accepted item.
|
||||
lv->mouse_activated ( lv, xce, lv->mouse_activated_data );
|
||||
}
|
||||
}
|
||||
else {
|
||||
listview_set_selected ( lv, lv->last_offset + i );
|
||||
}
|
||||
lv->last_click = xce->time;
|
||||
return TRUE;
|
||||
}
|
||||
unsigned int i;
|
||||
for ( i = 0; i < max && WIDGET ( lv->boxes[i] ) != wid; i++ ) {
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean listview_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
listview *lv = (listview *) wid;
|
||||
if ( widget_enabled ( WIDGET ( lv->scrollbar ) ) && lv->scrollbar_scroll ) {
|
||||
xcb_motion_notify_event_t xle = *xme;
|
||||
xle.event_x -= wid->x;
|
||||
xle.event_y -= wid->y;
|
||||
widget_motion_notify ( WIDGET ( lv->scrollbar ), &xle );
|
||||
return TRUE;
|
||||
if ( i == max ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
gboolean custom = FALSE;
|
||||
switch ( action )
|
||||
{
|
||||
case SELECT_HOVERED_ENTRY:
|
||||
listview_set_selected ( lv, lv->last_offset + i );
|
||||
break;
|
||||
case ACCEPT_HOVERED_CUSTOM:
|
||||
custom = TRUE;
|
||||
case ACCEPT_HOVERED_ENTRY:
|
||||
listview_set_selected ( lv, lv->last_offset + i );
|
||||
lv->mouse_activated ( lv, custom, lv->mouse_activated_data );
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
listview *listview_create ( const char *name, listview_update_callback cb, void *udata, unsigned int eh, gboolean reverse )
|
||||
{
|
||||
listview *lv = g_malloc0 ( sizeof ( listview ) );
|
||||
gchar *box = g_strjoin ( ".", name, "box", NULL );
|
||||
widget_init ( WIDGET ( lv ), box );
|
||||
widget_init ( WIDGET ( lv ), WIDGET_TYPE_LISTVIEW, box );
|
||||
g_free ( box );
|
||||
lv->listview_name = g_strdup ( name );
|
||||
lv->widget.free = listview_free;
|
||||
lv->widget.resize = listview_resize;
|
||||
lv->widget.draw = listview_draw;
|
||||
lv->widget.clicked = listview_clicked;
|
||||
lv->widget.motion_notify = listview_motion_notify;
|
||||
lv->widget.find_mouse_target = listview_find_mouse_target;
|
||||
lv->widget.trigger_action = listview_trigger_action;
|
||||
lv->widget.get_desired_height = listview_get_desired_height;
|
||||
lv->widget.enabled = rofi_theme_get_boolean ( WIDGET ( lv ), "enabled", TRUE );
|
||||
lv->eh = eh;
|
||||
|
@ -378,12 +402,11 @@ listview *listview_create ( const char *name, listview_update_callback cb, void
|
|||
// Default position on right.
|
||||
lv->scrollbar->widget.index = rofi_theme_get_integer_exact ( WIDGET ( lv->scrollbar ), "index", 1 );
|
||||
g_free ( n );
|
||||
widget_set_clicked_handler ( WIDGET ( lv->scrollbar ), listview_scrollbar_clicked, lv );
|
||||
lv->scrollbar->widget.parent = WIDGET ( lv );
|
||||
// Calculate height of an element.
|
||||
//
|
||||
char *tb_name = g_strjoin ( ".", lv->listview_name, "element", NULL );
|
||||
textbox *tb = textbox_create ( tb_name, 0, NORMAL, "" );
|
||||
textbox *tb = textbox_create_full ( WIDGET_TYPE_LISTVIEW_ELEMENT, tb_name, 0, NORMAL, "" );
|
||||
lv->element_height = textbox_get_estimated_height ( tb, lv->eh );
|
||||
g_free ( tb_name );
|
||||
widget_free ( WIDGET ( tb ) );
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
static void scrollbar_draw ( widget *, cairo_t * );
|
||||
static void scrollbar_free ( widget * );
|
||||
static gboolean scrollbar_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme );
|
||||
|
||||
static int scrollbar_get_desired_height ( widget *wid )
|
||||
{
|
||||
|
@ -45,10 +44,60 @@ static int scrollbar_get_desired_height ( widget *wid )
|
|||
return wid->h;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// This should behave more like a real scrollbar.
|
||||
unsigned int scrollbar_scroll ( const scrollbar *sb, int y )
|
||||
{
|
||||
if ( sb != NULL ) {
|
||||
if ( y >= sb->widget.y && y <= ( sb->widget.y + sb->widget.h ) ) {
|
||||
short r = ( sb->length * sb->widget.h ) / ( (double) ( sb->length + sb->pos_length ) );
|
||||
short handle = sb->widget.h - r;
|
||||
double sec = ( ( r ) / (double) ( sb->length - 1 ) );
|
||||
short half_handle = handle / 2;
|
||||
y -= sb->widget.y + half_handle;
|
||||
y = MIN ( MAX ( 0, y ), sb->widget.h - 2 * half_handle );
|
||||
|
||||
unsigned int sel = ( ( y ) / sec );
|
||||
return MIN ( sel, sb->length - 1 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gboolean scrollbar_trigger_action ( widget *wid, MouseBindingMouseDefaultAction action, G_GNUC_UNUSED gint x, gint y, G_GNUC_UNUSED void *user_data )
|
||||
{
|
||||
scrollbar *sb = (scrollbar *) wid;
|
||||
switch ( action )
|
||||
{
|
||||
case MOUSE_CLICK_DOWN:
|
||||
sb->scrolling = TRUE;
|
||||
return TRUE;
|
||||
case MOUSE_CLICK_UP:
|
||||
sb->scrolling = FALSE;
|
||||
/* FIXME: scoll
|
||||
scrollbar_scroll(sb, y);
|
||||
*/
|
||||
return TRUE;
|
||||
case MOUSE_DCLICK_DOWN:
|
||||
case MOUSE_DCLICK_UP:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean scrollbar_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
/* FIXME: scoll
|
||||
scrollbar *sb = (scrollbar *) wid;
|
||||
scrollbar_scroll(sb, xme->event_y);
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
scrollbar *scrollbar_create ( const char *name )
|
||||
{
|
||||
scrollbar *sb = g_malloc0 ( sizeof ( scrollbar ) );
|
||||
widget_init ( WIDGET ( sb ), name );
|
||||
widget_init ( WIDGET ( sb ), WIDGET_TYPE_SCROLLBAR, name );
|
||||
sb->widget.x = 0;
|
||||
sb->widget.y = 0;
|
||||
sb->width = rofi_theme_get_distance ( WIDGET ( sb ), "handle-width", DEFAULT_SCROLLBAR_WIDTH );
|
||||
|
@ -58,6 +107,7 @@ scrollbar *scrollbar_create ( const char *name )
|
|||
|
||||
sb->widget.draw = scrollbar_draw;
|
||||
sb->widget.free = scrollbar_free;
|
||||
sb->widget.trigger_action = scrollbar_trigger_action;
|
||||
sb->widget.motion_notify = scrollbar_motion_notify;
|
||||
sb->widget.get_desired_height = scrollbar_get_desired_height;
|
||||
|
||||
|
@ -134,30 +184,3 @@ static void scrollbar_draw ( widget *wid, cairo_t *draw )
|
|||
height );
|
||||
cairo_fill ( draw );
|
||||
}
|
||||
static gboolean scrollbar_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
{
|
||||
xcb_button_press_event_t xle;
|
||||
xle.event_x = xme->event_x;
|
||||
xle.event_y = xme->event_y;
|
||||
return widget_clicked ( WIDGET ( wid ), &xle );
|
||||
}
|
||||
|
||||
// TODO
|
||||
// This should behave more like a real scrollbar.
|
||||
unsigned int scrollbar_clicked ( const scrollbar *sb, int y )
|
||||
{
|
||||
if ( sb != NULL ) {
|
||||
if ( y >= sb->widget.y && y <= ( sb->widget.y + sb->widget.h ) ) {
|
||||
short r = ( sb->length * sb->widget.h ) / ( (double) ( sb->length + sb->pos_length ) );
|
||||
short handle = sb->widget.h - r;
|
||||
double sec = ( ( r ) / (double) ( sb->length - 1 ) );
|
||||
short half_handle = handle / 2;
|
||||
y -= sb->widget.y + half_handle;
|
||||
y = MIN ( MAX ( 0, y ), sb->widget.h - 2 * half_handle );
|
||||
|
||||
unsigned int sel = ( ( y ) / sec );
|
||||
return MIN ( sel, sb->length - 1 );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -106,11 +106,31 @@ static int textbox_get_desired_height ( widget *wid )
|
|||
return height;
|
||||
}
|
||||
|
||||
textbox* textbox_create ( const char *name, TextboxFlags flags, TextBoxFontType tbft, const char *text )
|
||||
static gboolean textbox_editable_trigger_action ( widget *wid, MouseBindingMouseDefaultAction action, gint x, gint y, G_GNUC_UNUSED void *user_data )
|
||||
{
|
||||
textbox *tb = (textbox *) wid;
|
||||
switch ( action )
|
||||
{
|
||||
case MOUSE_CLICK_DOWN:
|
||||
{
|
||||
gint i;
|
||||
pango_layout_xy_to_index ( tb->layout, x * PANGO_SCALE, y * PANGO_SCALE, &i, NULL );
|
||||
textbox_cursor ( tb, i );
|
||||
return TRUE;
|
||||
}
|
||||
case MOUSE_CLICK_UP:
|
||||
case MOUSE_DCLICK_DOWN:
|
||||
case MOUSE_DCLICK_UP:
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
textbox* textbox_create_full ( WidgetType type, const char *name, TextboxFlags flags, TextBoxFontType tbft, const char *text )
|
||||
{
|
||||
textbox *tb = g_slice_new0 ( textbox );
|
||||
|
||||
widget_init ( WIDGET ( tb ), name );
|
||||
widget_init ( WIDGET ( tb ), type, name );
|
||||
|
||||
tb->widget.draw = textbox_draw;
|
||||
tb->widget.free = textbox_free;
|
||||
|
@ -162,7 +182,8 @@ textbox* textbox_create ( const char *name, TextboxFlags flags, TextBoxFontType
|
|||
tb->blink_timeout = 0;
|
||||
tb->blink = 1;
|
||||
if ( ( flags & TB_EDITABLE ) == TB_EDITABLE ) {
|
||||
tb->blink_timeout = g_timeout_add ( 1200, textbox_blink, tb );
|
||||
tb->blink_timeout = g_timeout_add ( 1200, textbox_blink, tb );
|
||||
tb->widget.trigger_action = textbox_editable_trigger_action;
|
||||
}
|
||||
|
||||
// Enabled by default
|
||||
|
@ -799,13 +820,13 @@ int textbox_get_estimated_height ( const textbox *tb, int eh )
|
|||
}
|
||||
int textbox_get_desired_width ( widget *wid )
|
||||
{
|
||||
textbox *tb = (textbox *) wid;
|
||||
textbox *tb = (textbox *) wid;
|
||||
unsigned int offset = ( tb->flags & TB_INDICATOR ) ? DOT_OFFSET : 0;
|
||||
if ( tb->flags & TB_AUTOWIDTH ) {
|
||||
return textbox_get_font_width ( tb ) + widget_padding_get_padding_width ( wid ) + offset;
|
||||
}
|
||||
int width = 0;
|
||||
pango_layout_set_width ( tb->layout, -1);
|
||||
pango_layout_set_width ( tb->layout, -1 );
|
||||
width = textbox_get_font_width ( tb );
|
||||
// Restore.
|
||||
pango_layout_set_width ( tb->layout, PANGO_SCALE * ( tb->widget.w - widget_padding_get_padding_width ( WIDGET ( tb ) ) - offset ) );
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
/** Default padding. */
|
||||
#define WIDGET_DEFAULT_PADDING 0
|
||||
|
||||
void widget_init ( widget *widget, const char *name )
|
||||
void widget_init ( widget *widget, WidgetType type, const char *name )
|
||||
{
|
||||
widget->type = type;
|
||||
widget->name = g_strdup ( name );
|
||||
widget->def_padding = (Padding){ { WIDGET_DEFAULT_PADDING, PW_PX, SOLID }, { WIDGET_DEFAULT_PADDING, PW_PX, SOLID }, { WIDGET_DEFAULT_PADDING, PW_PX, SOLID }, { WIDGET_DEFAULT_PADDING, PW_PX, SOLID } };
|
||||
widget->def_border = (Padding){ { 0, PW_PX, SOLID }, { 0, PW_PX, SOLID }, { 0, PW_PX, SOLID }, { 0, PW_PX, SOLID } };
|
||||
|
@ -98,6 +99,14 @@ void widget_move ( widget *widget, short x, short y )
|
|||
}
|
||||
}
|
||||
|
||||
WidgetType widget_type ( widget *widget )
|
||||
{
|
||||
if ( widget != NULL ) {
|
||||
return widget->type;
|
||||
}
|
||||
return WIDGET_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
gboolean widget_enabled ( widget *widget )
|
||||
{
|
||||
if ( widget != NULL ) {
|
||||
|
@ -416,19 +425,41 @@ gboolean widget_need_redraw ( widget *wid )
|
|||
}
|
||||
return FALSE;
|
||||
}
|
||||
gboolean widget_clicked ( widget *wid, xcb_button_press_event_t *xbe )
|
||||
|
||||
widget *widget_find_mouse_target ( widget *wid, WidgetType type, gint *x, gint *y )
|
||||
{
|
||||
if ( wid && wid->clicked ) {
|
||||
return wid->clicked ( wid, xbe, wid->clicked_cb_data );
|
||||
if ( !wid ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( wid->find_mouse_target ) {
|
||||
widget *target = wid->find_mouse_target ( wid, type, x, y );
|
||||
if ( target != NULL ) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
if ( wid->type == type ) {
|
||||
return wid;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean widget_trigger_action ( widget *wid, guint action, gint x, gint y )
|
||||
{
|
||||
g_print ( "TRIGGER %p\n", wid );
|
||||
if ( wid && wid->trigger_action ) {
|
||||
return wid->trigger_action ( wid, action, x, y, wid->trigger_action_cb_data );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
void widget_set_clicked_handler ( widget *wid, widget_clicked_cb cb, void *udata )
|
||||
|
||||
void widget_set_trigger_action_handler ( widget *wid, widget_trigger_action_cb cb, void * cb_data )
|
||||
{
|
||||
if ( wid ) {
|
||||
wid->clicked = cb;
|
||||
wid->clicked_cb_data = udata;
|
||||
if ( wid->type == WIDGET_TYPE_SIDEBAR_MODI ) {
|
||||
g_print ( "CUSTOM TRIGGER %p\n", wid );
|
||||
}
|
||||
wid->trigger_action = cb;
|
||||
wid->trigger_action_cb_data = cb_data;
|
||||
}
|
||||
|
||||
gboolean widget_motion_notify ( widget *wid, xcb_motion_notify_event_t *xme )
|
||||
|
|
|
@ -88,8 +88,6 @@ const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
|||
* Holds for each supported modifier the possible modifier mask.
|
||||
* Check x11_mod_masks[MODIFIER]&mask != 0 to see if MODIFIER is activated.
|
||||
*/
|
||||
static unsigned int x11_mod_masks[NUM_X11MOD];
|
||||
|
||||
cairo_surface_t *x11_helper_get_screenshot_surface ( void )
|
||||
{
|
||||
return cairo_xcb_surface_create ( xcb->connection,
|
||||
|
@ -593,165 +591,6 @@ void release_pointer ( void )
|
|||
xcb_ungrab_pointer ( xcb->connection, XCB_CURRENT_TIME );
|
||||
}
|
||||
|
||||
static unsigned int x11_find_mod_mask ( xkb_stuff *xkb, ... )
|
||||
{
|
||||
va_list names;
|
||||
const char *name;
|
||||
xkb_mod_index_t i;
|
||||
unsigned int mask = 0;
|
||||
va_start ( names, xkb );
|
||||
while ( ( name = va_arg ( names, const char * ) ) != NULL ) {
|
||||
i = xkb_keymap_mod_get_index ( xkb->keymap, name );
|
||||
if ( i != XKB_MOD_INVALID ) {
|
||||
mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
va_end ( names );
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void x11_figure_out_masks ( xkb_stuff *xkb )
|
||||
{
|
||||
x11_mod_masks[X11MOD_SHIFT] = x11_find_mod_mask ( xkb, XKB_MOD_NAME_SHIFT, NULL );
|
||||
x11_mod_masks[X11MOD_CONTROL] = x11_find_mod_mask ( xkb, XKB_MOD_NAME_CTRL, NULL );
|
||||
x11_mod_masks[X11MOD_ALT] = x11_find_mod_mask ( xkb, XKB_MOD_NAME_ALT, "Alt", "LAlt", "RAlt", "AltGr", "Mod5", "LevelThree", NULL );
|
||||
x11_mod_masks[X11MOD_META] = x11_find_mod_mask ( xkb, "Meta", NULL );
|
||||
x11_mod_masks[X11MOD_SUPER] = x11_find_mod_mask ( xkb, XKB_MOD_NAME_LOGO, "Super", NULL );
|
||||
x11_mod_masks[X11MOD_HYPER] = x11_find_mod_mask ( xkb, "Hyper", NULL );
|
||||
|
||||
gsize i;
|
||||
for ( i = 0; i < X11MOD_ANY; ++i ) {
|
||||
x11_mod_masks[X11MOD_ANY] |= x11_mod_masks[i];
|
||||
}
|
||||
}
|
||||
|
||||
int x11_modifier_active ( unsigned int mask, int key )
|
||||
{
|
||||
return ( x11_mod_masks[key] & mask ) != 0;
|
||||
}
|
||||
|
||||
unsigned int x11_canonalize_mask ( unsigned int mask )
|
||||
{
|
||||
// Bits 13 and 14 of the modifiers together are the group number, and
|
||||
// should be ignored when looking up key bindings
|
||||
mask &= x11_mod_masks[X11MOD_ANY];
|
||||
|
||||
gsize i;
|
||||
for ( i = 0; i < X11MOD_ANY; ++i ) {
|
||||
if ( mask & x11_mod_masks[i] ) {
|
||||
mask |= x11_mod_masks[i];
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
unsigned int x11_get_current_mask ( xkb_stuff *xkb )
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
for ( gsize i = 0; i < xkb_keymap_num_mods ( xkb->keymap ); ++i ) {
|
||||
if ( xkb_state_mod_index_is_active ( xkb->state, i, XKB_STATE_MODS_EFFECTIVE ) ) {
|
||||
mask |= ( 1 << i );
|
||||
}
|
||||
}
|
||||
return x11_canonalize_mask ( mask );
|
||||
}
|
||||
|
||||
// convert a Mod+key arg to mod mask and keysym
|
||||
gboolean x11_parse_key ( const char *combo, unsigned int *mod, xkb_keysym_t *key, gboolean *release, GString *str )
|
||||
{
|
||||
char *input_key = g_strdup ( combo );
|
||||
char *mod_key = input_key;
|
||||
char *error_msg = NULL;
|
||||
unsigned int last_modmask = 0;
|
||||
unsigned int modmask = 0;
|
||||
xkb_keysym_t last_sym = XKB_KEY_NoSymbol;
|
||||
xkb_keysym_t sym = XKB_KEY_NoSymbol;
|
||||
// Test if this works on release.
|
||||
if ( g_str_has_prefix ( mod_key, "!" ) ) {
|
||||
++mod_key;
|
||||
*release = TRUE;
|
||||
}
|
||||
|
||||
char **entries = g_strsplit_set ( mod_key, "+-", -1 );
|
||||
for ( int i = 0; entries && entries[i]; i++ ) {
|
||||
char *entry = entries[i];
|
||||
// Remove trailing and leading spaces.
|
||||
entry = g_strstrip ( entry );
|
||||
// Compare against lowered version.
|
||||
last_modmask = modmask;
|
||||
last_sym = xkb_keysym_from_name ( entry, XKB_KEYSYM_NO_FLAGS );
|
||||
char *entry_lowered = g_utf8_strdown ( entry, -1 );
|
||||
if ( g_utf8_collate ( entry_lowered, "shift" ) == 0 ) {
|
||||
modmask |= x11_mod_masks[X11MOD_SHIFT];
|
||||
if ( x11_mod_masks[X11MOD_SHIFT] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Shift</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else if ( g_utf8_collate ( entry_lowered, "control" ) == 0 ) {
|
||||
modmask |= x11_mod_masks[X11MOD_CONTROL];
|
||||
if ( x11_mod_masks[X11MOD_CONTROL] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Control</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else if ( g_utf8_collate ( entry_lowered, "alt" ) == 0 ) {
|
||||
modmask |= x11_mod_masks[X11MOD_ALT];
|
||||
if ( x11_mod_masks[X11MOD_ALT] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Alt</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else if ( g_utf8_collate ( entry_lowered, "super" ) == 0 ||
|
||||
g_utf8_collate ( entry_lowered, "super_l" ) == 0 ||
|
||||
g_utf8_collate ( entry_lowered, "super_r" ) == 0
|
||||
) {
|
||||
modmask |= x11_mod_masks[X11MOD_SUPER];
|
||||
if ( x11_mod_masks[X11MOD_SUPER] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Super</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else if ( g_utf8_collate ( entry_lowered, "meta" ) == 0 ) {
|
||||
modmask |= x11_mod_masks[X11MOD_META];
|
||||
if ( x11_mod_masks[X11MOD_META] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Meta</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else if ( g_utf8_collate ( entry_lowered, "hyper" ) == 0 ) {
|
||||
modmask |= x11_mod_masks[X11MOD_HYPER];
|
||||
if ( x11_mod_masks[X11MOD_HYPER] == 0 ) {
|
||||
error_msg = g_strdup ( "X11 configured keyboard has no <b>Hyper</b> key.\n" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( sym != XKB_KEY_NoSymbol ) {
|
||||
error_msg = g_markup_printf_escaped ( "Only one (non modifier) key can be bound per binding: <b>%s</b> is invalid.\n", entry );
|
||||
}
|
||||
sym = last_sym;
|
||||
if ( sym == XKB_KEY_NoSymbol ) {
|
||||
error_msg = g_markup_printf_escaped ( "∙ Key <i>%s</i> is not understood\n", entry );
|
||||
}
|
||||
}
|
||||
g_free ( entry_lowered );
|
||||
}
|
||||
g_strfreev ( entries );
|
||||
|
||||
g_free ( input_key );
|
||||
if ( ( sym == XKB_KEY_NoSymbol ) && ( last_sym != XKB_KEY_NoSymbol ) ) {
|
||||
sym = last_sym;
|
||||
modmask = last_modmask;
|
||||
}
|
||||
|
||||
if ( error_msg ) {
|
||||
char *name = g_markup_escape_text ( combo, -1 );
|
||||
g_string_append_printf ( str, "Cannot understand the key combination: <i>%s</i>\n", name );
|
||||
g_string_append ( str, error_msg );
|
||||
g_free ( name );
|
||||
g_free ( error_msg );
|
||||
return FALSE;
|
||||
}
|
||||
*key = sym;
|
||||
*mod = modmask;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill in the list of frequently used X11 Atoms.
|
||||
*/
|
||||
|
@ -768,10 +607,9 @@ static void x11_create_frequently_used_atoms ( void )
|
|||
}
|
||||
}
|
||||
|
||||
void x11_setup ( xkb_stuff *xkb )
|
||||
void x11_setup ( void )
|
||||
{
|
||||
// determine numlock mask so we can bind on keys with and without it
|
||||
x11_figure_out_masks ( xkb );
|
||||
x11_create_frequently_used_atoms ( );
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
#include <xcb/xcb.h>
|
||||
#include <xcb/xkb.h>
|
||||
#include <xcb/xcb_xrm.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
#include <glib.h>
|
||||
#include "xcb.h"
|
||||
#include "xcb-internal.h"
|
||||
|
|
1
subprojects/libnkutils
Submodule
1
subprojects/libnkutils
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 697263d2b74aeea2222c100e4079176091971aca
|
|
@ -216,12 +216,15 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
|||
//box_set_padding ( b, 5 );
|
||||
widget *wid1 = g_malloc0(sizeof(widget));
|
||||
widget_enable(wid1);
|
||||
wid1->clicked = test_widget_clicked;
|
||||
//FIXME: see below
|
||||
//wid1->clicked = test_widget_clicked;
|
||||
box_add ( b , WIDGET( wid1 ), TRUE, 0 );
|
||||
widget *wid2 = g_malloc0(sizeof(widget));
|
||||
widget_enable(wid2);
|
||||
box_add ( b , WIDGET( wid2 ), TRUE, 1 );
|
||||
|
||||
/*FIXME: fix code for binding rework???
|
||||
* maybe test the find_mouse_target instead
|
||||
xcb_button_press_event_t xce;
|
||||
xce.event_x = 10;
|
||||
xce.event_y = 60;
|
||||
|
@ -238,5 +241,6 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
|||
widget_enable ( wid2 );
|
||||
TASSERTE ( widget_clicked ( WIDGET(b), &xce ), 0);
|
||||
widget_free ( WIDGET ( b ) );
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,14 +69,10 @@ RofiViewState * rofi_view_get_active ( void )
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
gboolean rofi_view_trigger_action ( G_GNUC_UNUSED RofiViewState *state, G_GNUC_UNUSED KeyBindingAction action )
|
||||
gboolean rofi_view_trigger_action ( G_GNUC_UNUSED guint scope, G_GNUC_UNUSED gpointer user_data )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
gboolean x11_parse_key ( G_GNUC_UNUSED const char *combo, G_GNUC_UNUSED unsigned int *mod, G_GNUC_UNUSED xkb_keysym_t *key, G_GNUC_UNUSED gboolean *release, G_GNUC_UNUSED GString *msg )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
#ifndef _ck_assert_ptr_null
|
||||
/* Pointer against NULL comparison macros with improved output
|
||||
* compared to ck_assert(). */
|
||||
|
@ -121,10 +117,10 @@ START_TEST(test_mode_num_items)
|
|||
for ( unsigned int i =0; i < rows; i++ ){
|
||||
int state = 0;
|
||||
GList *list = NULL;
|
||||
char *v = mode_get_display_value ( &help_keys_mode, i, &state, &list, TRUE );
|
||||
char *v = mode_get_display_value ( &help_keys_mode, i, &state, &list, TRUE );
|
||||
ck_assert_ptr_nonnull ( v );
|
||||
g_free ( v );
|
||||
v = mode_get_display_value ( &help_keys_mode, i, &state, &list, FALSE );
|
||||
v = mode_get_display_value ( &help_keys_mode, i, &state, &list, FALSE );
|
||||
ck_assert_ptr_null ( v );
|
||||
}
|
||||
mode_destroy ( &help_keys_mode );
|
||||
|
|
|
@ -103,22 +103,22 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
|||
TASSERTE ( sb->pos_length, 1 );
|
||||
|
||||
|
||||
unsigned int cl = scrollbar_clicked ( sb, 10 );
|
||||
unsigned int cl = scrollbar_scroll ( sb, 10 );
|
||||
TASSERTE ( cl, 1010);
|
||||
cl = scrollbar_clicked ( sb, 20 );
|
||||
cl = scrollbar_scroll ( sb, 20 );
|
||||
TASSERTE ( cl, 2020);
|
||||
cl = scrollbar_clicked ( sb, 0 );
|
||||
cl = scrollbar_scroll ( sb, 0 );
|
||||
TASSERTE ( cl, 0);
|
||||
cl = scrollbar_clicked ( sb, 99 );
|
||||
cl = scrollbar_scroll ( sb, 99 );
|
||||
TASSERTE ( cl, 9999);
|
||||
scrollbar_set_handle_length ( sb, 1000);
|
||||
cl = scrollbar_clicked ( sb, 10 );
|
||||
cl = scrollbar_scroll ( sb, 10 );
|
||||
TASSERTE ( cl, 555);
|
||||
cl = scrollbar_clicked ( sb, 20 );
|
||||
cl = scrollbar_scroll ( sb, 20 );
|
||||
TASSERTE ( cl, 1666);
|
||||
cl = scrollbar_clicked ( sb, 0 );
|
||||
cl = scrollbar_scroll ( sb, 0 );
|
||||
TASSERTE ( cl, 0);
|
||||
cl = scrollbar_clicked ( sb, 99 );
|
||||
cl = scrollbar_scroll ( sb, 99 );
|
||||
TASSERTE ( cl, 9999);
|
||||
|
||||
widget_free( WIDGET (sb ) );
|
||||
|
|
|
@ -189,8 +189,10 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
|||
widget_update ( NULL );
|
||||
widget_queue_redraw ( NULL );
|
||||
TASSERT (widget_need_redraw ( NULL ) == FALSE);
|
||||
/* FIXME: add relevant code for binding rework
|
||||
widget_clicked ( NULL, NULL );
|
||||
widget_set_clicked_handler ( NULL, NULL, NULL );
|
||||
*/
|
||||
|
||||
|
||||
g_free(wid);
|
||||
|
|
Loading…
Add table
Reference in a new issue