mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-25 13:55:34 -05:00
Indent the bunch with my astyle line.
This commit is contained in:
parent
bad311adab
commit
b47f22ca51
3 changed files with 961 additions and 886 deletions
8
Makefile
8
Makefile
|
@ -24,12 +24,16 @@ normal:
|
||||||
debug:
|
debug:
|
||||||
$(CC) -o simpleswitcher-debug simpleswitcher.c -std=c99 $(CFLAGS) -Wunused-parameter -g -DDEBUG $(LDADD)
|
$(CC) -o simpleswitcher-debug simpleswitcher.c -std=c99 $(CFLAGS) -Wunused-parameter -g -DDEBUG $(LDADD)
|
||||||
|
|
||||||
install: install-man
|
install: normal install-man
|
||||||
install -Dm 755 simpleswitcher $(BINDIR)/simpleswitcher
|
install -Dm 755 simpleswitcher $(BINDIR)/simpleswitcher
|
||||||
|
|
||||||
install-man:
|
install-man:
|
||||||
install -Dm 644 simpleswitcher.1 $(MANDIR)
|
install -Dm 644 simpleswitcher.1 $(MANDIR)
|
||||||
gzip $(MANDIR)/simpleswitcher.1
|
gzip -f $(MANDIR)/simpleswitcher.1
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f simpleswitcher simpleswitcher-debug
|
rm -f simpleswitcher simpleswitcher-debug
|
||||||
|
|
||||||
|
|
||||||
|
indent:
|
||||||
|
@astyle --style=linux -S -C -D -N -H -L -W3 -f simpleswitcher.c textbox.c
|
||||||
|
|
411
simpleswitcher.c
411
simpleswitcher.c
|
@ -61,11 +61,12 @@
|
||||||
static void* allocate( unsigned long bytes )
|
static void* allocate( unsigned long bytes )
|
||||||
{
|
{
|
||||||
void *ptr = malloc( bytes );
|
void *ptr = malloc( bytes );
|
||||||
if (!ptr)
|
|
||||||
{
|
if ( !ptr ) {
|
||||||
fprintf( stderr, "malloc failed!\n" );
|
fprintf( stderr, "malloc failed!\n" );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
static void* allocate_clear( unsigned long bytes )
|
static void* allocate_clear( unsigned long bytes )
|
||||||
|
@ -77,17 +78,19 @@ static void* allocate_clear(unsigned long bytes)
|
||||||
static void* reallocate( void *ptr, unsigned long bytes )
|
static void* reallocate( void *ptr, unsigned long bytes )
|
||||||
{
|
{
|
||||||
ptr = realloc( ptr, bytes );
|
ptr = realloc( ptr, bytes );
|
||||||
if (!ptr)
|
|
||||||
{
|
if ( !ptr ) {
|
||||||
fprintf( stderr, "realloc failed!\n" );
|
fprintf( stderr, "realloc failed!\n" );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char **tokenize( const char *input )
|
static inline char **tokenize( const char *input )
|
||||||
{
|
{
|
||||||
if ( input == NULL ) return NULL;
|
if ( input == NULL ) return NULL;
|
||||||
|
|
||||||
char *saveptr = NULL, *token;
|
char *saveptr = NULL, *token;
|
||||||
char **retv = NULL;
|
char **retv = NULL;
|
||||||
// First entry is always full (modified) stringtext.
|
// First entry is always full (modified) stringtext.
|
||||||
|
@ -102,8 +105,7 @@ static inline char **tokenize(const char *input)
|
||||||
for (
|
for (
|
||||||
token = strtok_r( retv[0], " ", &saveptr );
|
token = strtok_r( retv[0], " ", &saveptr );
|
||||||
token != NULL;
|
token != NULL;
|
||||||
token = strtok_r(NULL, " ", &saveptr))
|
token = strtok_r( NULL, " ", &saveptr ) ) {
|
||||||
{
|
|
||||||
retv = realloc( retv, sizeof( char* )*( num_tokens+2 ) );
|
retv = realloc( retv, sizeof( char* )*( num_tokens+2 ) );
|
||||||
retv[num_tokens+1] = NULL;
|
retv[num_tokens+1] = NULL;
|
||||||
retv[num_tokens] = token;
|
retv[num_tokens] = token;
|
||||||
|
@ -116,8 +118,10 @@ static inline char **tokenize(const char *input)
|
||||||
static inline void tokenize_free( char **ip )
|
static inline void tokenize_free( char **ip )
|
||||||
{
|
{
|
||||||
if ( ip == NULL ) return;
|
if ( ip == NULL ) return;
|
||||||
|
|
||||||
if ( ip[0] )
|
if ( ip[0] )
|
||||||
free( ip[0] );
|
free( ip[0] );
|
||||||
|
|
||||||
free( ip );
|
free( ip );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,21 +140,25 @@ int execsh(char *cmd)
|
||||||
pid_t exec_cmd( char *cmd )
|
pid_t exec_cmd( char *cmd )
|
||||||
{
|
{
|
||||||
if ( !cmd || !cmd[0] ) return -1;
|
if ( !cmd || !cmd[0] ) return -1;
|
||||||
|
|
||||||
signal( SIGCHLD, catch_exit );
|
signal( SIGCHLD, catch_exit );
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (!pid)
|
|
||||||
{
|
if ( !pid ) {
|
||||||
setsid();
|
setsid();
|
||||||
execsh( cmd );
|
execsh( cmd );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
// cli arg handling
|
// cli arg handling
|
||||||
static int find_arg( const int argc, char * const argv[], const char * const key )
|
static int find_arg( const int argc, char * const argv[], const char * const key )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for ( i = 0; i < argc && strcasecmp( argv[i], key ); i++ );
|
for ( i = 0; i < argc && strcasecmp( argv[i], key ); i++ );
|
||||||
|
|
||||||
return i < argc ? i: -1;
|
return i < argc ? i: -1;
|
||||||
}
|
}
|
||||||
static char* find_arg_str( int argc, char *argv[], char *key, char* def )
|
static char* find_arg_str( int argc, char *argv[], char *key, char* def )
|
||||||
|
@ -165,7 +173,8 @@ static int find_arg_int(int argc, char *argv[], char *key, int def)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int NumlockMask = 0;
|
unsigned int NumlockMask = 0;
|
||||||
Display *display; Screen *screen;
|
Display *display;
|
||||||
|
Screen *screen;
|
||||||
Window root;
|
Window root;
|
||||||
int screen_id;
|
int screen_id;
|
||||||
|
|
||||||
|
@ -228,6 +237,7 @@ int oops(__attribute__((unused)) Display *d, XErrorEvent *ee)
|
||||||
|| ( ee->request_code == X_GrabButton && ee->error_code == BadAccess )
|
|| ( ee->request_code == X_GrabButton && ee->error_code == BadAccess )
|
||||||
|| ( ee->request_code == X_GrabKey && ee->error_code == BadAccess )
|
|| ( ee->request_code == X_GrabKey && ee->error_code == BadAccess )
|
||||||
) return 0;
|
) return 0;
|
||||||
|
|
||||||
fprintf( stderr, "error: request code=%d, error code=%d\n", ee->request_code, ee->error_code );
|
fprintf( stderr, "error: request code=%d, error code=%d\n", ee->request_code, ee->error_code );
|
||||||
return xerror( display, ee );
|
return xerror( display, ee );
|
||||||
}
|
}
|
||||||
|
@ -255,18 +265,19 @@ winlist *cache_xattr;
|
||||||
|
|
||||||
winlist* winlist_new()
|
winlist* winlist_new()
|
||||||
{
|
{
|
||||||
winlist *l = allocate(sizeof(winlist)); l->len = 0;
|
winlist *l = allocate( sizeof( winlist ) );
|
||||||
|
l->len = 0;
|
||||||
l->array = allocate( sizeof( Window ) * ( WINLIST+1 ) );
|
l->array = allocate( sizeof( Window ) * ( WINLIST+1 ) );
|
||||||
l->data = allocate( sizeof( void* ) * ( WINLIST+1 ) );
|
l->data = allocate( sizeof( void* ) * ( WINLIST+1 ) );
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
int winlist_append( winlist *l, Window w, void *d )
|
int winlist_append( winlist *l, Window w, void *d )
|
||||||
{
|
{
|
||||||
if (l->len > 0 && !(l->len % WINLIST))
|
if ( l->len > 0 && !( l->len % WINLIST ) ) {
|
||||||
{
|
|
||||||
l->array = reallocate( l->array, sizeof( Window ) * ( l->len+WINLIST+1 ) );
|
l->array = reallocate( l->array, sizeof( Window ) * ( l->len+WINLIST+1 ) );
|
||||||
l->data = reallocate( l->data, sizeof( void* ) * ( l->len+WINLIST+1 ) );
|
l->data = reallocate( l->data, sizeof( void* ) * ( l->len+WINLIST+1 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
l->data[l->len] = d;
|
l->data[l->len] = d;
|
||||||
l->array[l->len++] = w;
|
l->array[l->len++] = w;
|
||||||
return l->len-1;
|
return l->len-1;
|
||||||
|
@ -277,7 +288,10 @@ void winlist_empty(winlist *l)
|
||||||
}
|
}
|
||||||
void winlist_free( winlist *l )
|
void winlist_free( winlist *l )
|
||||||
{
|
{
|
||||||
winlist_empty(l); free(l->array); free(l->data); free(l);
|
winlist_empty( l );
|
||||||
|
free( l->array );
|
||||||
|
free( l->data );
|
||||||
|
free( l );
|
||||||
}
|
}
|
||||||
void winlist_empty_2d( winlist *l )
|
void winlist_empty_2d( winlist *l )
|
||||||
{
|
{
|
||||||
|
@ -287,18 +301,27 @@ int winlist_find(winlist *l, Window w)
|
||||||
{
|
{
|
||||||
// iterate backwards. theory is: windows most often accessed will be
|
// iterate backwards. theory is: windows most often accessed will be
|
||||||
// nearer the end. testing with kcachegrind seems to support this...
|
// nearer the end. testing with kcachegrind seems to support this...
|
||||||
int i; Window o; winlist_descend(l, i, o) if (w == o) return i;
|
int i;
|
||||||
|
Window o;
|
||||||
|
|
||||||
|
winlist_descend( l, i, o ) if ( w == o ) return i;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int winlist_forget( winlist *l, Window w )
|
int winlist_forget( winlist *l, Window w )
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0, j = 0; i < l->len; i++, j++)
|
|
||||||
{
|
for ( i = 0, j = 0; i < l->len; i++, j++ ) {
|
||||||
l->array[j] = l->array[i];
|
l->array[j] = l->array[i];
|
||||||
l->data[j] = l->data[i];
|
l->data[j] = l->data[i];
|
||||||
if (l->array[i] == w) { free(l->data[i]); j--; }
|
|
||||||
|
if ( l->array[i] == w ) {
|
||||||
|
free( l->data[i] );
|
||||||
|
j--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
l->len -= ( i-j );
|
l->len -= ( i-j );
|
||||||
return j != i ?1:0;
|
return j != i ?1:0;
|
||||||
}
|
}
|
||||||
|
@ -358,25 +381,32 @@ static unsigned int color_get(const char *const name)
|
||||||
// find mouse pointer location
|
// find mouse pointer location
|
||||||
int pointer_get( Window root, int *x, int *y )
|
int pointer_get( Window root, int *x, int *y )
|
||||||
{
|
{
|
||||||
*x = 0; *y = 0;
|
*x = 0;
|
||||||
Window rr, cr; int rxr, ryr, wxr, wyr; unsigned int mr;
|
*y = 0;
|
||||||
if (XQueryPointer(display, root, &rr, &cr, &rxr, &ryr, &wxr, &wyr, &mr))
|
Window rr, cr;
|
||||||
{
|
int rxr, ryr, wxr, wyr;
|
||||||
*x = rxr; *y = ryr;
|
unsigned int mr;
|
||||||
|
|
||||||
|
if ( XQueryPointer( display, root, &rr, &cr, &rxr, &ryr, &wxr, &wyr, &mr ) ) {
|
||||||
|
*x = rxr;
|
||||||
|
*y = ryr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int take_keyboard( Window w )
|
int take_keyboard( Window w )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 1000; i++)
|
|
||||||
{
|
for ( i = 0; i < 1000; i++ ) {
|
||||||
if ( XGrabKeyboard( display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime ) == GrabSuccess )
|
if ( XGrabKeyboard( display, w, True, GrabModeAsync, GrabModeAsync, CurrentTime ) == GrabSuccess )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
usleep( 1000 );
|
usleep( 1000 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void release_keyboard()
|
void release_keyboard()
|
||||||
|
@ -388,37 +418,51 @@ void release_keyboard()
|
||||||
XWindowAttributes* window_get_attributes( Window w )
|
XWindowAttributes* window_get_attributes( Window w )
|
||||||
{
|
{
|
||||||
int idx = winlist_find( cache_xattr, w );
|
int idx = winlist_find( cache_xattr, w );
|
||||||
if (idx < 0)
|
|
||||||
{
|
if ( idx < 0 ) {
|
||||||
XWindowAttributes *cattr = allocate( sizeof( XWindowAttributes ) );
|
XWindowAttributes *cattr = allocate( sizeof( XWindowAttributes ) );
|
||||||
if (XGetWindowAttributes(display, w, cattr))
|
|
||||||
{
|
if ( XGetWindowAttributes( display, w, cattr ) ) {
|
||||||
winlist_append( cache_xattr, w, cattr );
|
winlist_append( cache_xattr, w, cattr );
|
||||||
return cattr;
|
return cattr;
|
||||||
}
|
}
|
||||||
|
|
||||||
free( cattr );
|
free( cattr );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache_xattr->data[idx];
|
return cache_xattr->data[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve a property of any type from a window
|
// retrieve a property of any type from a window
|
||||||
int window_get_prop( Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes )
|
int window_get_prop( Window w, Atom prop, Atom *type, int *items, void *buffer, unsigned int bytes )
|
||||||
{
|
{
|
||||||
Atom _type; if (!type) type = &_type;
|
Atom _type;
|
||||||
int _items; if (!items) items = &_items;
|
|
||||||
int format; unsigned long nitems, nbytes; unsigned char *ret = NULL;
|
if ( !type ) type = &_type;
|
||||||
|
|
||||||
|
int _items;
|
||||||
|
|
||||||
|
if ( !items ) items = &_items;
|
||||||
|
|
||||||
|
int format;
|
||||||
|
unsigned long nitems, nbytes;
|
||||||
|
unsigned char *ret = NULL;
|
||||||
memset( buffer, 0, bytes );
|
memset( buffer, 0, bytes );
|
||||||
|
|
||||||
if ( XGetWindowProperty( display, w, prop, 0, bytes/4, False, AnyPropertyType, type,
|
if ( XGetWindowProperty( display, w, prop, 0, bytes/4, False, AnyPropertyType, type,
|
||||||
&format, &nitems, &nbytes, &ret) == Success && ret && *type != None && format)
|
&format, &nitems, &nbytes, &ret ) == Success && ret && *type != None && format ) {
|
||||||
{
|
|
||||||
if ( format == 8 ) memmove( buffer, ret, MIN( bytes, nitems ) );
|
if ( format == 8 ) memmove( buffer, ret, MIN( bytes, nitems ) );
|
||||||
|
|
||||||
if ( format == 16 ) memmove( buffer, ret, MIN( bytes, nitems * sizeof( short ) ) );
|
if ( format == 16 ) memmove( buffer, ret, MIN( bytes, nitems * sizeof( short ) ) );
|
||||||
|
|
||||||
if ( format == 32 ) memmove( buffer, ret, MIN( bytes, nitems * sizeof( long ) ) );
|
if ( format == 32 ) memmove( buffer, ret, MIN( bytes, nitems * sizeof( long ) ) );
|
||||||
*items = (int)nitems; XFree(ret);
|
|
||||||
|
*items = ( int )nitems;
|
||||||
|
XFree( ret );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,30 +470,31 @@ int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, u
|
||||||
// technically we could use window_get_prop(), but this is better for character set support
|
// technically we could use window_get_prop(), but this is better for character set support
|
||||||
char* window_get_text_prop( Window w, Atom atom )
|
char* window_get_text_prop( Window w, Atom atom )
|
||||||
{
|
{
|
||||||
XTextProperty prop; char *res = NULL;
|
XTextProperty prop;
|
||||||
char **list = NULL; int count;
|
char *res = NULL;
|
||||||
if (XGetTextProperty(display, w, &prop, atom) && prop.value && prop.nitems)
|
char **list = NULL;
|
||||||
{
|
int count;
|
||||||
if (prop.encoding == XA_STRING)
|
|
||||||
{
|
if ( XGetTextProperty( display, w, &prop, atom ) && prop.value && prop.nitems ) {
|
||||||
|
if ( prop.encoding == XA_STRING ) {
|
||||||
res = allocate( strlen( ( char* )prop.value )+1 );
|
res = allocate( strlen( ( char* )prop.value )+1 );
|
||||||
strcpy( res, ( char* )prop.value );
|
strcpy( res, ( char* )prop.value );
|
||||||
}
|
} else if ( XmbTextPropertyToTextList( display, &prop, &list, &count ) >= Success && count > 0 && *list ) {
|
||||||
else
|
|
||||||
if (XmbTextPropertyToTextList(display, &prop, &list, &count) >= Success && count > 0 && *list)
|
|
||||||
{
|
|
||||||
res = allocate( strlen( *list )+1 );
|
res = allocate( strlen( *list )+1 );
|
||||||
strcpy( res, *list );
|
strcpy( res, *list );
|
||||||
XFreeStringList( list );
|
XFreeStringList( list );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( prop.value ) XFree( prop.value );
|
if ( prop.value ) XFree( prop.value );
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int window_get_atom_prop( Window w, Atom atom, Atom *list, int count )
|
int window_get_atom_prop( Window w, Atom atom, Atom *list, int count )
|
||||||
{
|
{
|
||||||
Atom type; int items;
|
Atom type;
|
||||||
|
int items;
|
||||||
return window_get_prop( w, atom, &type, &items, list, count*sizeof( Atom ) ) && type == XA_ATOM ? items:0;
|
return window_get_prop( w, atom, &type, &items, list, count*sizeof( Atom ) ) && type == XA_ATOM ? items:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,18 +505,23 @@ void window_set_atom_prop(Window w, Atom prop, Atom *atoms, int count)
|
||||||
|
|
||||||
int window_get_cardinal_prop( Window w, Atom atom, unsigned long *list, int count )
|
int window_get_cardinal_prop( Window w, Atom atom, unsigned long *list, int count )
|
||||||
{
|
{
|
||||||
Atom type; int items;
|
Atom type;
|
||||||
|
int items;
|
||||||
return window_get_prop( w, atom, &type, &items, list, count*sizeof( unsigned long ) ) && type == XA_CARDINAL ? items:0;
|
return window_get_prop( w, atom, &type, &items, list, count*sizeof( unsigned long ) ) && type == XA_CARDINAL ? items:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a ClientMessage
|
// a ClientMessage
|
||||||
int window_send_message( Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask, Time time )
|
int window_send_message( Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask, Time time )
|
||||||
{
|
{
|
||||||
XEvent e; memset(&e, 0, sizeof(XEvent));
|
XEvent e;
|
||||||
|
memset( &e, 0, sizeof( XEvent ) );
|
||||||
e.xclient.type = ClientMessage;
|
e.xclient.type = ClientMessage;
|
||||||
e.xclient.message_type = atom; e.xclient.window = subject;
|
e.xclient.message_type = atom;
|
||||||
e.xclient.data.l[0] = protocol; e.xclient.data.l[1] = time;
|
e.xclient.window = subject;
|
||||||
e.xclient.send_event = True; e.xclient.format = 32;
|
e.xclient.data.l[0] = protocol;
|
||||||
|
e.xclient.data.l[1] = time;
|
||||||
|
e.xclient.send_event = True;
|
||||||
|
e.xclient.format = 32;
|
||||||
int r = XSendEvent( display, target, False, mask, &e ) ?1:0;
|
int r = XSendEvent( display, target, False, mask, &e ) ?1:0;
|
||||||
XFlush( display );
|
XFlush( display );
|
||||||
return r;
|
return r;
|
||||||
|
@ -485,19 +535,20 @@ void monitor_dimensions(Screen *screen, int x, int y, workarea *mon)
|
||||||
mon->h = HeightOfScreen( screen );
|
mon->h = HeightOfScreen( screen );
|
||||||
|
|
||||||
// locate the current monitor
|
// locate the current monitor
|
||||||
if (XineramaIsActive(display))
|
if ( XineramaIsActive( display ) ) {
|
||||||
{
|
|
||||||
int monitors, i;
|
int monitors, i;
|
||||||
XineramaScreenInfo *info = XineramaQueryScreens( display, &monitors );
|
XineramaScreenInfo *info = XineramaQueryScreens( display, &monitors );
|
||||||
if (info) for (i = 0; i < monitors; i++)
|
|
||||||
{
|
if ( info ) for ( i = 0; i < monitors; i++ ) {
|
||||||
if (INTERSECT(x, y, 1, 1, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
|
if ( INTERSECT( x, y, 1, 1, info[i].x_org, info[i].y_org, info[i].width, info[i].height ) ) {
|
||||||
{
|
mon->x = info[i].x_org;
|
||||||
mon->x = info[i].x_org; mon->y = info[i].y_org;
|
mon->y = info[i].y_org;
|
||||||
mon->w = info[i].width; mon->h = info[i].height;
|
mon->w = info[i].width;
|
||||||
|
mon->h = info[i].height;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XFree( info );
|
XFree( info );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,20 +558,24 @@ void monitor_active(workarea *mon)
|
||||||
{
|
{
|
||||||
Window root = RootWindow( display, XScreenNumberOfScreen( screen ) );
|
Window root = RootWindow( display, XScreenNumberOfScreen( screen ) );
|
||||||
|
|
||||||
unsigned long id; Atom type; int count;
|
unsigned long id;
|
||||||
|
Atom type;
|
||||||
|
int count;
|
||||||
|
|
||||||
if ( window_get_prop( root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &id, 1 )
|
if ( window_get_prop( root, netatoms[_NET_ACTIVE_WINDOW], &type, &count, &id, 1 )
|
||||||
&& type == XA_WINDOW && count > 0)
|
&& type == XA_WINDOW && count > 0 ) {
|
||||||
{
|
|
||||||
XWindowAttributes *attr = window_get_attributes( id );
|
XWindowAttributes *attr = window_get_attributes( id );
|
||||||
monitor_dimensions( screen, attr->x, attr->y, mon );
|
monitor_dimensions( screen, attr->x, attr->y, mon );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
if (pointer_get(root, &x, &y))
|
|
||||||
{
|
if ( pointer_get( root, &x, &y ) ) {
|
||||||
monitor_dimensions( screen, x, y, mon );
|
monitor_dimensions( screen, x, y, mon );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor_dimensions( screen, 0, 0, mon );
|
monitor_dimensions( screen, 0, 0, mon );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,8 +583,10 @@ void monitor_active(workarea *mon)
|
||||||
int client_has_state( client *c, Atom state )
|
int client_has_state( client *c, Atom state )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for ( i = 0; i < c->states; i++ )
|
for ( i = 0; i < c->states; i++ )
|
||||||
if ( c->state[i] == state ) return 1;
|
if ( c->state[i] == state ) return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,11 +595,14 @@ int client_has_state(client *c, Atom state)
|
||||||
client* window_client( Window win )
|
client* window_client( Window win )
|
||||||
{
|
{
|
||||||
if ( win == None ) return NULL;
|
if ( win == None ) return NULL;
|
||||||
|
|
||||||
int idx = winlist_find( cache_client, win );
|
int idx = winlist_find( cache_client, win );
|
||||||
|
|
||||||
if ( idx >= 0 ) return cache_client->data[idx];
|
if ( idx >= 0 ) return cache_client->data[idx];
|
||||||
|
|
||||||
// if this fails, we're up that creek
|
// if this fails, we're up that creek
|
||||||
XWindowAttributes *attr = window_get_attributes( win );
|
XWindowAttributes *attr = window_get_attributes( win );
|
||||||
|
|
||||||
if ( !attr ) return NULL;
|
if ( !attr ) return NULL;
|
||||||
|
|
||||||
client *c = allocate_clear( sizeof( client ) );
|
client *c = allocate_clear( sizeof( client ) );
|
||||||
|
@ -561,24 +621,24 @@ client* window_client(Window win)
|
||||||
: netatoms[_NET_WM_WINDOW_TYPE_NORMAL];
|
: netatoms[_NET_WM_WINDOW_TYPE_NORMAL];
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
if ((name = window_get_text_prop(c->window, netatoms[_NET_WM_NAME])) && name)
|
|
||||||
{
|
if ( ( name = window_get_text_prop( c->window, netatoms[_NET_WM_NAME] ) ) && name ) {
|
||||||
snprintf( c->title, CLIENTTITLE, "%s", name );
|
snprintf( c->title, CLIENTTITLE, "%s", name );
|
||||||
free( name );
|
free( name );
|
||||||
}
|
} else if ( XFetchName( display, c->window, &name ) ) {
|
||||||
else
|
|
||||||
if (XFetchName(display, c->window, &name))
|
|
||||||
{
|
|
||||||
snprintf( c->title, CLIENTTITLE, "%s", name );
|
snprintf( c->title, CLIENTTITLE, "%s", name );
|
||||||
XFree( name );
|
XFree( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
XClassHint chint;
|
XClassHint chint;
|
||||||
if (XGetClassHint(display, c->window, &chint))
|
|
||||||
{
|
if ( XGetClassHint( display, c->window, &chint ) ) {
|
||||||
snprintf( c->class, CLIENTCLASS, "%s", chint.res_class );
|
snprintf( c->class, CLIENTCLASS, "%s", chint.res_class );
|
||||||
snprintf( c->name, CLIENTNAME, "%s", chint.res_name );
|
snprintf( c->name, CLIENTNAME, "%s", chint.res_name );
|
||||||
XFree(chint.res_class); XFree(chint.res_name);
|
XFree( chint.res_class );
|
||||||
|
XFree( chint.res_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor_dimensions( c->xattr.screen, c->xattr.x, c->xattr.y, &c->monitor );
|
monitor_dimensions( c->xattr.screen, c->xattr.x, c->xattr.y, &c->monitor );
|
||||||
winlist_append( cache_client, c->window, c );
|
winlist_append( cache_client, c->window, c );
|
||||||
return c;
|
return c;
|
||||||
|
@ -587,7 +647,8 @@ client* window_client(Window win)
|
||||||
#define ALLWINDOWS 1
|
#define ALLWINDOWS 1
|
||||||
#define DESKTOPWINDOWS 2
|
#define DESKTOPWINDOWS 2
|
||||||
|
|
||||||
unsigned int windows_modmask; KeySym windows_keysym;
|
unsigned int windows_modmask;
|
||||||
|
KeySym windows_keysym;
|
||||||
// flags to set if we switch modes on the fly
|
// flags to set if we switch modes on the fly
|
||||||
int run_windows = 0;
|
int run_windows = 0;
|
||||||
Window main_window = None;
|
Window main_window = None;
|
||||||
|
@ -598,8 +659,8 @@ void menu_draw(textbox *text, textbox **boxes, int max_lines, int selected, char
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
textbox_draw( text );
|
textbox_draw( text );
|
||||||
for (i = 0; i < max_lines; i++)
|
|
||||||
{
|
for ( i = 0; i < max_lines; i++ ) {
|
||||||
textbox_font( boxes[i], config_menu_font,
|
textbox_font( boxes[i], config_menu_font,
|
||||||
i == selected ? config_menu_hlfg: config_menu_fg,
|
i == selected ? config_menu_hlfg: config_menu_fg,
|
||||||
i == selected ? config_menu_hlbg: config_menu_bg );
|
i == selected ? config_menu_hlbg: config_menu_bg );
|
||||||
|
@ -615,31 +676,42 @@ void menu_draw(textbox *text, textbox **boxes, int max_lines, int selected, char
|
||||||
static int calculate_common_prefix( char **filtered, int max_lines )
|
static int calculate_common_prefix( char **filtered, int max_lines )
|
||||||
{
|
{
|
||||||
int length_prefix = 0,j,found = 1;
|
int length_prefix = 0,j,found = 1;
|
||||||
|
|
||||||
if ( filtered[0] != NULL ) {
|
if ( filtered[0] != NULL ) {
|
||||||
char *p = filtered[0];
|
char *p = filtered[0];
|
||||||
|
|
||||||
do {
|
do {
|
||||||
found = 1;
|
found = 1;
|
||||||
|
|
||||||
for ( j=0; j < max_lines && filtered[j] != NULL; j++ ) {
|
for ( j=0; j < max_lines && filtered[j] != NULL; j++ ) {
|
||||||
if ( filtered[j][length_prefix] == '\0' || filtered[j][length_prefix] != *p ) {
|
if ( filtered[j][length_prefix] == '\0' || filtered[j][length_prefix] != *p ) {
|
||||||
if ( found )
|
if ( found )
|
||||||
found=0;
|
found=0;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( found )
|
if ( found )
|
||||||
length_prefix++;
|
length_prefix++;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
} while ( found );
|
} while ( found );
|
||||||
}
|
}
|
||||||
|
|
||||||
return length_prefix;
|
return length_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
int menu( char **lines, char **input, char *prompt, int selected, Time *time )
|
int menu( char **lines, char **input, char *prompt, int selected, Time *time )
|
||||||
{
|
{
|
||||||
int line = -1, i, j, chosen = 0, aborted = 0;
|
int line = -1, i, j, chosen = 0, aborted = 0;
|
||||||
workarea mon; monitor_active(&mon);
|
workarea mon;
|
||||||
|
monitor_active( &mon );
|
||||||
|
|
||||||
|
int num_lines = 0;
|
||||||
|
|
||||||
|
for ( ; lines[num_lines]; num_lines++ );
|
||||||
|
|
||||||
int num_lines = 0; for (; lines[num_lines]; num_lines++);
|
|
||||||
int max_lines = MIN( config_menu_lines, num_lines );
|
int max_lines = MIN( config_menu_lines, num_lines );
|
||||||
selected = MAX( MIN( num_lines-1, selected ), 0 );
|
selected = MAX( MIN( num_lines-1, selected ), 0 );
|
||||||
|
|
||||||
|
@ -650,18 +722,16 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
|
|
||||||
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
|
// main window isn't explicitly destroyed in case we switch modes. Reusing it prevents flicker
|
||||||
if (main_window != None && XGetWindowAttributes(display, main_window, &attr))
|
if ( main_window != None && XGetWindowAttributes( display, main_window, &attr ) ) {
|
||||||
{
|
|
||||||
box = main_window;
|
box = main_window;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
box = XCreateSimpleWindow( display, root, x, 0, w, 300, 1, color_get( config_menu_bc ), color_get( config_menu_bg ) );
|
box = XCreateSimpleWindow( display, root, x, 0, w, 300, 1, color_get( config_menu_bc ), color_get( config_menu_bg ) );
|
||||||
XSelectInput( display, box, ExposureMask );
|
XSelectInput( display, box, ExposureMask );
|
||||||
// make it an unmanaged window
|
// make it an unmanaged window
|
||||||
window_set_atom_prop( box, netatoms[_NET_WM_STATE], &netatoms[_NET_WM_STATE_ABOVE], 1 );
|
window_set_atom_prop( box, netatoms[_NET_WM_STATE], &netatoms[_NET_WM_STATE_ABOVE], 1 );
|
||||||
//window_set_atom_prop(box, netatoms[_NET_WM_WINDOW_TYPE], &netatoms[_NET_WM_WINDOW_TYPE_DOCK], 1);
|
//window_set_atom_prop(box, netatoms[_NET_WM_WINDOW_TYPE], &netatoms[_NET_WM_WINDOW_TYPE_DOCK], 1);
|
||||||
XSetWindowAttributes sattr; sattr.override_redirect = True;
|
XSetWindowAttributes sattr;
|
||||||
|
sattr.override_redirect = True;
|
||||||
XChangeWindowAttributes( display, box, CWOverrideRedirect, &sattr );
|
XChangeWindowAttributes( display, box, CWOverrideRedirect, &sattr );
|
||||||
main_window = box;
|
main_window = box;
|
||||||
|
|
||||||
|
@ -686,8 +756,7 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
// filtered list display
|
// filtered list display
|
||||||
textbox **boxes = allocate_clear( sizeof( textbox* ) * max_lines );
|
textbox **boxes = allocate_clear( sizeof( textbox* ) * max_lines );
|
||||||
|
|
||||||
for (i = 0; i < max_lines; i++)
|
for ( i = 0; i < max_lines; i++ ) {
|
||||||
{
|
|
||||||
boxes[i] = textbox_create( box, TB_AUTOHEIGHT, 5, ( i+1 ) * line_height + 5, w-10, 1,
|
boxes[i] = textbox_create( box, TB_AUTOHEIGHT, 5, ( i+1 ) * line_height + 5, w-10, 1,
|
||||||
config_menu_font, config_menu_fg, config_menu_bg, lines[i], NULL );
|
config_menu_font, config_menu_fg, config_menu_bg, lines[i], NULL );
|
||||||
textbox_show( boxes[i] );
|
textbox_show( boxes[i] );
|
||||||
|
@ -699,8 +768,8 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
int filtered_lines = 0;
|
int filtered_lines = 0;
|
||||||
|
|
||||||
int jin = 0;
|
int jin = 0;
|
||||||
for (i = 0; i < max_lines; i++)
|
|
||||||
{
|
for ( i = 0; i < max_lines; i++ ) {
|
||||||
filtered[jin] = lines[i];
|
filtered[jin] = lines[i];
|
||||||
line_map[jin] = i;
|
line_map[jin] = i;
|
||||||
jin++;
|
jin++;
|
||||||
|
@ -714,90 +783,87 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
XMapRaised( display, box );
|
XMapRaised( display, box );
|
||||||
|
|
||||||
take_keyboard( box );
|
take_keyboard( box );
|
||||||
for (;;)
|
|
||||||
{
|
for ( ;; ) {
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
XNextEvent( display, &ev );
|
XNextEvent( display, &ev );
|
||||||
|
|
||||||
if (ev.type == Expose)
|
if ( ev.type == Expose ) {
|
||||||
{
|
|
||||||
while ( XCheckTypedEvent( display, Expose, &ev ) );
|
while ( XCheckTypedEvent( display, Expose, &ev ) );
|
||||||
|
|
||||||
menu_draw( text, boxes, max_lines, selected, filtered );
|
menu_draw( text, boxes, max_lines, selected, filtered );
|
||||||
}
|
} else if ( ev.type == KeyPress ) {
|
||||||
else
|
|
||||||
if (ev.type == KeyPress)
|
|
||||||
{
|
|
||||||
while ( XCheckTypedEvent( display, KeyPress, &ev ) );
|
while ( XCheckTypedEvent( display, KeyPress, &ev ) );
|
||||||
|
|
||||||
if ( time )
|
if ( time )
|
||||||
*time = ev.xkey.time;
|
*time = ev.xkey.time;
|
||||||
|
|
||||||
int rc = textbox_keypress( text, &ev );
|
int rc = textbox_keypress( text, &ev );
|
||||||
if (rc < 0)
|
|
||||||
{
|
if ( rc < 0 ) {
|
||||||
chosen = 1;
|
chosen = 1;
|
||||||
break;
|
break;
|
||||||
}
|
} else if ( rc ) {
|
||||||
else
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
char **tokens = tokenize( text->text );
|
char **tokens = tokenize( text->text );
|
||||||
|
|
||||||
// input changed
|
// input changed
|
||||||
for (i = 0, j = 0; i < num_lines && j < max_lines; i++)
|
for ( i = 0, j = 0; i < num_lines && j < max_lines; i++ ) {
|
||||||
{
|
|
||||||
int match = 1;
|
int match = 1;
|
||||||
|
|
||||||
// Do a tokenized match.
|
// Do a tokenized match.
|
||||||
if(tokens) for(int j = 1; match && tokens[j]; j++)
|
if ( tokens ) for ( int j = 1; match && tokens[j]; j++ ) {
|
||||||
{
|
|
||||||
match = ( strcasestr( lines[i], tokens[j] ) != NULL );
|
match = ( strcasestr( lines[i], tokens[j] ) != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If each token was matched, add it to list.
|
// If each token was matched, add it to list.
|
||||||
if(match)
|
if ( match ) {
|
||||||
{
|
|
||||||
line_map[j] = i;
|
line_map[j] = i;
|
||||||
filtered[j++] = lines[i];
|
filtered[j++] = lines[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup + bookkeeping.
|
// Cleanup + bookkeeping.
|
||||||
filtered_lines = j;
|
filtered_lines = j;
|
||||||
selected = MAX( 0, MIN( selected, j-1 ) );
|
selected = MAX( 0, MIN( selected, j-1 ) );
|
||||||
|
|
||||||
for ( ; j < max_lines; j++ )
|
for ( ; j < max_lines; j++ )
|
||||||
filtered[j] = NULL;
|
filtered[j] = NULL;
|
||||||
|
|
||||||
if ( config_zeltak_mode && filtered_lines == 1 ) {
|
if ( config_zeltak_mode && filtered_lines == 1 ) {
|
||||||
chosen = 1;
|
chosen = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenize_free( tokens );
|
tokenize_free( tokens );
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// unhandled key
|
// unhandled key
|
||||||
KeySym key = XkbKeycodeToKeysym( display, ev.xkey.keycode, 0, 0 );
|
KeySym key = XkbKeycodeToKeysym( display, ev.xkey.keycode, 0, 0 );
|
||||||
|
|
||||||
if ( key == XK_Escape
|
if ( key == XK_Escape
|
||||||
// pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected
|
// pressing one of the global key bindings closes the switcher. this allows fast closing of the menu if an item is not selected
|
||||||
|| ( ( windows_modmask == AnyModifier || ev.xkey.state & windows_modmask ) && key == windows_keysym )
|
|| ( ( windows_modmask == AnyModifier || ev.xkey.state & windows_modmask ) && key == windows_keysym )
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
aborted = 1;
|
aborted = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
// Up or Shift-Tab
|
// Up or Shift-Tab
|
||||||
if ( key == XK_Up || ( key == XK_Tab && ev.xkey.state & ShiftMask ) )
|
if ( key == XK_Up || ( key == XK_Tab && ev.xkey.state & ShiftMask ) )
|
||||||
selected = selected ? MAX( 0, selected-1 ): MAX( 0, filtered_lines-1 );
|
selected = selected ? MAX( 0, selected-1 ): MAX( 0, filtered_lines-1 );
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
// Down or Tab
|
// Down or Tab
|
||||||
if (key == XK_Down || key == XK_Tab)
|
if ( key == XK_Down || key == XK_Tab ) {
|
||||||
{
|
|
||||||
if ( filtered_lines == 1 ) {
|
if ( filtered_lines == 1 ) {
|
||||||
chosen = 1;
|
chosen = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int length_prefix = calculate_common_prefix( filtered, max_lines );
|
int length_prefix = calculate_common_prefix( filtered, max_lines );
|
||||||
|
|
||||||
if ( length_prefix && strncasecmp( filtered[0], text->text, length_prefix ) ) {
|
if ( length_prefix && strncasecmp( filtered[0], text->text, length_prefix ) ) {
|
||||||
// Do not want to modify original string, so make copy.
|
// Do not want to modify original string, so make copy.
|
||||||
// not eff..
|
// not eff..
|
||||||
|
@ -805,14 +871,15 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
textbox_text( text, str );
|
textbox_text( text, str );
|
||||||
textbox_cursor_end( text );
|
textbox_cursor_end( text );
|
||||||
free( str );
|
free( str );
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
selected = selected < filtered_lines-1 ? MIN( filtered_lines-1, selected+1 ): 0;
|
selected = selected < filtered_lines-1 ? MIN( filtered_lines-1, selected+1 ): 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
menu_draw( text, boxes, max_lines, selected, filtered );
|
menu_draw( text, boxes, max_lines, selected, filtered );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_keyboard();
|
release_keyboard();
|
||||||
|
|
||||||
if ( chosen && filtered[selected] )
|
if ( chosen && filtered[selected] )
|
||||||
|
@ -822,6 +889,7 @@ int menu(char **lines, char **input, char *prompt, int selected, Time *time)
|
||||||
*input = strdup( text->text );
|
*input = strdup( text->text );
|
||||||
|
|
||||||
textbox_free( text );
|
textbox_free( text );
|
||||||
|
|
||||||
for ( i = 0; i < max_lines; i++ )
|
for ( i = 0; i < max_lines; i++ )
|
||||||
textbox_free( boxes[i] );
|
textbox_free( boxes[i] );
|
||||||
|
|
||||||
|
@ -845,9 +913,9 @@ void run_switcher(int fmode)
|
||||||
// this also happens to isolate the Xft font stuff in a child process
|
// this also happens to isolate the Xft font stuff in a child process
|
||||||
// that gets cleaned up every time. that library shows some valgrind
|
// that gets cleaned up every time. that library shows some valgrind
|
||||||
// strangeness...
|
// strangeness...
|
||||||
if (fmode == FORK)
|
if ( fmode == FORK ) {
|
||||||
{
|
|
||||||
if ( fork() ) return;
|
if ( fork() ) return;
|
||||||
|
|
||||||
display = XOpenDisplay( 0 );
|
display = XOpenDisplay( 0 );
|
||||||
XSync( display, True );
|
XSync( display, True );
|
||||||
}
|
}
|
||||||
|
@ -858,7 +926,8 @@ void run_switcher(int fmode)
|
||||||
int i, plen = 0, lines = 0;
|
int i, plen = 0, lines = 0;
|
||||||
unsigned int classfield = 0;
|
unsigned int classfield = 0;
|
||||||
unsigned long desktops = 0, current_desktop = 0;
|
unsigned long desktops = 0, current_desktop = 0;
|
||||||
Window w; client *c;
|
Window w;
|
||||||
|
client *c;
|
||||||
|
|
||||||
// windows we actually display. may be slightly different to _NET_CLIENT_LIST_STACKING
|
// windows we actually display. may be slightly different to _NET_CLIENT_LIST_STACKING
|
||||||
// if we happen to have a window destroyed while we're working...
|
// if we happen to have a window destroyed while we're working...
|
||||||
|
@ -868,21 +937,23 @@ void run_switcher(int fmode)
|
||||||
current_desktop = 0;
|
current_desktop = 0;
|
||||||
|
|
||||||
// find window list
|
// find window list
|
||||||
Atom type; int nwins; unsigned long *wins = allocate_clear(sizeof(unsigned long) * 100);
|
Atom type;
|
||||||
|
int nwins;
|
||||||
|
unsigned long *wins = allocate_clear( sizeof( unsigned long ) * 100 );
|
||||||
|
|
||||||
if ( window_get_prop( root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, 100 * sizeof( unsigned long ) )
|
if ( window_get_prop( root, netatoms[_NET_CLIENT_LIST_STACKING], &type, &nwins, wins, 100 * sizeof( unsigned long ) )
|
||||||
&& type == XA_WINDOW)
|
&& type == XA_WINDOW ) {
|
||||||
{
|
|
||||||
// calc widths of fields
|
// calc widths of fields
|
||||||
for (i = nwins-1; i > -1; i--)
|
for ( i = nwins-1; i > -1; i-- ) {
|
||||||
{
|
|
||||||
if ( ( c = window_client( wins[i] ) )
|
if ( ( c = window_client( wins[i] ) )
|
||||||
&& !c->xattr.override_redirect
|
&& !c->xattr.override_redirect
|
||||||
&& !client_has_state( c, netatoms[_NET_WM_STATE_SKIP_PAGER] )
|
&& !client_has_state( c, netatoms[_NET_WM_STATE_SKIP_PAGER] )
|
||||||
&& !client_has_state(c, netatoms[_NET_WM_STATE_SKIP_TASKBAR]))
|
&& !client_has_state( c, netatoms[_NET_WM_STATE_SKIP_TASKBAR] ) ) {
|
||||||
{
|
|
||||||
classfield = MAX( classfield, strlen( c->class ) );
|
classfield = MAX( classfield, strlen( c->class ) );
|
||||||
|
|
||||||
// In i3 mode, skip the i3bar completely.
|
// In i3 mode, skip the i3bar completely.
|
||||||
if ( config_i3_mode && strstr( c->class, "i3bar" ) != NULL ) continue;
|
if ( config_i3_mode && strstr( c->class, "i3bar" ) != NULL ) continue;
|
||||||
|
|
||||||
winlist_append( ids, c->window, NULL );
|
winlist_append( ids, c->window, NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -892,13 +963,12 @@ void run_switcher(int fmode)
|
||||||
|
|
||||||
|
|
||||||
plen += sprintf( pattern+plen, "%%-%ds %%s", MAX( 5, classfield ) );
|
plen += sprintf( pattern+plen, "%%-%ds %%s", MAX( 5, classfield ) );
|
||||||
list = allocate_clear(sizeof(char*) * (ids->len+1)); lines = 0;
|
list = allocate_clear( sizeof( char* ) * ( ids->len+1 ) );
|
||||||
|
lines = 0;
|
||||||
|
|
||||||
// build the actual list
|
// build the actual list
|
||||||
winlist_ascend(ids, i, w)
|
winlist_ascend( ids, i, w ) {
|
||||||
{
|
if ( ( c = window_client( w ) ) ) {
|
||||||
if ((c = window_client(w)))
|
|
||||||
{
|
|
||||||
// final line format
|
// final line format
|
||||||
char *line = allocate( strlen( c->title ) + strlen( c->class ) + classfield + 50 );
|
char *line = allocate( strlen( c->title ) + strlen( c->class ) + classfield + 50 );
|
||||||
|
|
||||||
|
@ -910,43 +980,41 @@ void run_switcher(int fmode)
|
||||||
char *input = NULL;
|
char *input = NULL;
|
||||||
Time time;
|
Time time;
|
||||||
int n = menu( list, &input, "> ", 1, &time );
|
int n = menu( list, &input, "> ", 1, &time );
|
||||||
if (n >= 0 && list[n])
|
|
||||||
{
|
if ( n >= 0 && list[n] ) {
|
||||||
if(config_i3_mode)
|
if ( config_i3_mode ) {
|
||||||
{
|
|
||||||
// Hack for i3.
|
// Hack for i3.
|
||||||
char array[128];
|
char array[128];
|
||||||
snprintf( array,128,"i3-msg [id=\"%d\"] focus",( int )( ids->array[n] ) );
|
snprintf( array,128,"i3-msg [id=\"%d\"] focus",( int )( ids->array[n] ) );
|
||||||
printf( "Executing: %s\n", array );
|
printf( "Executing: %s\n", array );
|
||||||
exec_cmd( array );
|
exec_cmd( array );
|
||||||
}
|
} else {
|
||||||
else
|
if ( isdigit( list[n][0] ) ) {
|
||||||
{
|
|
||||||
if (isdigit(list[n][0]))
|
|
||||||
{
|
|
||||||
// TODO: get rid of strtol
|
// TODO: get rid of strtol
|
||||||
window_send_message( root, root, netatoms[_NET_CURRENT_DESKTOP], strtol( list[n], NULL, 10 )-1,
|
window_send_message( root, root, netatoms[_NET_CURRENT_DESKTOP], strtol( list[n], NULL, 10 )-1,
|
||||||
SubstructureNotifyMask | SubstructureRedirectMask, time );
|
SubstructureNotifyMask | SubstructureRedirectMask, time );
|
||||||
XSync( display, False );
|
XSync( display, False );
|
||||||
}
|
}
|
||||||
|
|
||||||
window_send_message( root, ids->array[n], netatoms[_NET_ACTIVE_WINDOW], 2, // 2 = pager
|
window_send_message( root, ids->array[n], netatoms[_NET_ACTIVE_WINDOW], 2, // 2 = pager
|
||||||
SubstructureNotifyMask | SubstructureRedirectMask, time );
|
SubstructureNotifyMask | SubstructureRedirectMask, time );
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
// act as a launcher
|
// act as a launcher
|
||||||
if (input)
|
if ( input ) {
|
||||||
{
|
|
||||||
exec_cmd( input );
|
exec_cmd( input );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i = 0; i < lines; i++ )
|
for ( i = 0; i < lines; i++ )
|
||||||
free( list[i] );
|
free( list[i] );
|
||||||
|
|
||||||
free( list );
|
free( list );
|
||||||
}
|
}
|
||||||
|
|
||||||
free( wins );
|
free( wins );
|
||||||
winlist_free( ids );
|
winlist_free( ids );
|
||||||
}
|
} while ( run_windows );
|
||||||
while (run_windows );
|
|
||||||
|
|
||||||
if ( fmode == FORK )
|
if ( fmode == FORK )
|
||||||
exit( EXIT_SUCCESS );
|
exit( EXIT_SUCCESS );
|
||||||
|
@ -965,24 +1033,34 @@ void handle_keypress(XEvent *ev)
|
||||||
void parse_key( char *combo, unsigned int *mod, KeySym *key )
|
void parse_key( char *combo, unsigned int *mod, KeySym *key )
|
||||||
{
|
{
|
||||||
unsigned int modmask = 0;
|
unsigned int modmask = 0;
|
||||||
|
|
||||||
if ( strcasestr( combo, "shift" ) ) modmask |= ShiftMask;
|
if ( strcasestr( combo, "shift" ) ) modmask |= ShiftMask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "control" ) ) modmask |= ControlMask;
|
if ( strcasestr( combo, "control" ) ) modmask |= ControlMask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "mod1" ) ) modmask |= Mod1Mask;
|
if ( strcasestr( combo, "mod1" ) ) modmask |= Mod1Mask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "mod2" ) ) modmask |= Mod2Mask;
|
if ( strcasestr( combo, "mod2" ) ) modmask |= Mod2Mask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "mod3" ) ) modmask |= Mod3Mask;
|
if ( strcasestr( combo, "mod3" ) ) modmask |= Mod3Mask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "mod4" ) ) modmask |= Mod4Mask;
|
if ( strcasestr( combo, "mod4" ) ) modmask |= Mod4Mask;
|
||||||
|
|
||||||
if ( strcasestr( combo, "mod5" ) ) modmask |= Mod5Mask;
|
if ( strcasestr( combo, "mod5" ) ) modmask |= Mod5Mask;
|
||||||
|
|
||||||
*mod = modmask ? modmask: AnyModifier;
|
*mod = modmask ? modmask: AnyModifier;
|
||||||
|
|
||||||
char i = strlen( combo );
|
char i = strlen( combo );
|
||||||
|
|
||||||
while ( i > 0 && !strchr( "-+", combo[i-1] ) ) i--;
|
while ( i > 0 && !strchr( "-+", combo[i-1] ) ) i--;
|
||||||
|
|
||||||
KeySym sym = XStringToKeysym( combo+i );
|
KeySym sym = XStringToKeysym( combo+i );
|
||||||
if (sym == NoSymbol || (!modmask && (strchr(combo, '-') || strchr(combo, '+'))))
|
|
||||||
{
|
if ( sym == NoSymbol || ( !modmask && ( strchr( combo, '-' ) || strchr( combo, '+' ) ) ) ) {
|
||||||
fprintf( stderr, "sorry, cannot understand key combination: %s\n", combo );
|
fprintf( stderr, "sorry, cannot understand key combination: %s\n", combo );
|
||||||
exit( EXIT_FAILURE );
|
exit( EXIT_FAILURE );
|
||||||
}
|
}
|
||||||
|
|
||||||
*key = sym;
|
*key = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,19 +1070,16 @@ void grab_key(unsigned int modmask, KeySym key)
|
||||||
KeyCode keycode = XKeysymToKeycode( display, key );
|
KeyCode keycode = XKeysymToKeycode( display, key );
|
||||||
XUngrabKey( display, keycode, AnyModifier, root );
|
XUngrabKey( display, keycode, AnyModifier, root );
|
||||||
|
|
||||||
if (modmask != AnyModifier)
|
if ( modmask != AnyModifier ) {
|
||||||
{
|
|
||||||
// bind to combinations of mod and lock masks, so caps and numlock don't confuse people
|
// bind to combinations of mod and lock masks, so caps and numlock don't confuse people
|
||||||
XGrabKey( display, keycode, modmask, root, True, GrabModeAsync, GrabModeAsync );
|
XGrabKey( display, keycode, modmask, root, True, GrabModeAsync, GrabModeAsync );
|
||||||
XGrabKey( display, keycode, modmask|LockMask, root, True, GrabModeAsync, GrabModeAsync );
|
XGrabKey( display, keycode, modmask|LockMask, root, True, GrabModeAsync, GrabModeAsync );
|
||||||
if (NumlockMask)
|
|
||||||
{
|
if ( NumlockMask ) {
|
||||||
XGrabKey( display, keycode, modmask|NumlockMask, root, True, GrabModeAsync, GrabModeAsync );
|
XGrabKey( display, keycode, modmask|NumlockMask, root, True, GrabModeAsync, GrabModeAsync );
|
||||||
XGrabKey( display, keycode, modmask|NumlockMask|LockMask, root, True, GrabModeAsync, GrabModeAsync );
|
XGrabKey( display, keycode, modmask|NumlockMask|LockMask, root, True, GrabModeAsync, GrabModeAsync );
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// nice simple single key bind
|
// nice simple single key bind
|
||||||
XGrabKey( display, keycode, AnyModifier, root, True, GrabModeAsync, GrabModeAsync );
|
XGrabKey( display, keycode, AnyModifier, root, True, GrabModeAsync, GrabModeAsync );
|
||||||
}
|
}
|
||||||
|
@ -1017,32 +1092,37 @@ int main(int argc, char *argv[])
|
||||||
// catch help request
|
// catch help request
|
||||||
if ( find_arg( argc, argv, "-help" ) >= 0
|
if ( find_arg( argc, argv, "-help" ) >= 0
|
||||||
|| find_arg( argc, argv, "--help" ) >= 0
|
|| find_arg( argc, argv, "--help" ) >= 0
|
||||||
|| find_arg(argc, argv, "-h") >= 0)
|
|| find_arg( argc, argv, "-h" ) >= 0 ) {
|
||||||
{
|
|
||||||
fprintf( stderr, "See the man page or visit http://github.com/DaveDavenport/simpleswitcher\n" );
|
fprintf( stderr, "See the man page or visit http://github.com/DaveDavenport/simpleswitcher\n" );
|
||||||
fprintf( stderr, "Original code can be found: http://github.com/seanpringle/simpleswitcher\n" );
|
fprintf( stderr, "Original code can be found: http://github.com/seanpringle/simpleswitcher\n" );
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if(!(display = XOpenDisplay(0)))
|
|
||||||
{
|
if ( !( display = XOpenDisplay( 0 ) ) ) {
|
||||||
fprintf( stderr, "cannot open display!\n" );
|
fprintf( stderr, "cannot open display!\n" );
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal( SIGCHLD, catch_exit );
|
signal( SIGCHLD, catch_exit );
|
||||||
screen = DefaultScreenOfDisplay( display );
|
screen = DefaultScreenOfDisplay( display );
|
||||||
screen_id = DefaultScreen( display );
|
screen_id = DefaultScreen( display );
|
||||||
root = DefaultRootWindow( display );
|
root = DefaultRootWindow( display );
|
||||||
XSync(display, False); xerror = XSetErrorHandler(oops); XSync(display, False);
|
XSync( display, False );
|
||||||
|
xerror = XSetErrorHandler( oops );
|
||||||
|
XSync( display, False );
|
||||||
|
|
||||||
// determine numlock mask so we can bind on keys with and without it
|
// determine numlock mask so we can bind on keys with and without it
|
||||||
XModifierKeymap *modmap = XGetModifierMapping( display );
|
XModifierKeymap *modmap = XGetModifierMapping( display );
|
||||||
|
|
||||||
for ( i = 0; i < 8; i++ )
|
for ( i = 0; i < 8; i++ )
|
||||||
for ( j = 0; j < ( int )modmap->max_keypermod; j++ )
|
for ( j = 0; j < ( int )modmap->max_keypermod; j++ )
|
||||||
if ( modmap->modifiermap[i*modmap->max_keypermod+j] == XKeysymToKeycode( display, XK_Num_Lock ) )
|
if ( modmap->modifiermap[i*modmap->max_keypermod+j] == XKeysymToKeycode( display, XK_Num_Lock ) )
|
||||||
NumlockMask = ( 1<<i );
|
NumlockMask = ( 1<<i );
|
||||||
|
|
||||||
XFreeModifiermap( modmap );
|
XFreeModifiermap( modmap );
|
||||||
|
|
||||||
int ac = argc; char **av = argv;
|
int ac = argc;
|
||||||
|
char **av = argv;
|
||||||
cache_client = winlist_new();
|
cache_client = winlist_new();
|
||||||
cache_xattr = winlist_new();
|
cache_xattr = winlist_new();
|
||||||
|
|
||||||
|
@ -1065,8 +1145,7 @@ int main(int argc, char *argv[])
|
||||||
config_i3_mode = ( find_arg( ac, av, "-i3" ) >= 0 );
|
config_i3_mode = ( find_arg( ac, av, "-i3" ) >= 0 );
|
||||||
|
|
||||||
// flags to run immediately and exit
|
// flags to run immediately and exit
|
||||||
if (find_arg(ac, av, "-now") >= 0)
|
if ( find_arg( ac, av, "-now" ) >= 0 ) {
|
||||||
{
|
|
||||||
run_switcher( NOFORK );
|
run_switcher( NOFORK );
|
||||||
exit( EXIT_SUCCESS );
|
exit( EXIT_SUCCESS );
|
||||||
}
|
}
|
||||||
|
@ -1081,17 +1160,19 @@ int main(int argc, char *argv[])
|
||||||
grab_key( windows_modmask, windows_keysym );
|
grab_key( windows_modmask, windows_keysym );
|
||||||
|
|
||||||
XEvent ev;
|
XEvent ev;
|
||||||
for (;;)
|
|
||||||
{
|
for ( ;; ) {
|
||||||
// caches only live for a single event
|
// caches only live for a single event
|
||||||
winlist_empty( cache_xattr );
|
winlist_empty( cache_xattr );
|
||||||
winlist_empty( cache_client );
|
winlist_empty( cache_client );
|
||||||
|
|
||||||
// block and wait for something
|
// block and wait for something
|
||||||
XNextEvent( display, &ev );
|
XNextEvent( display, &ev );
|
||||||
|
|
||||||
if ( ev.xany.window == None ) continue;
|
if ( ev.xany.window == None ) continue;
|
||||||
|
|
||||||
if ( ev.type == KeyPress ) handle_keypress( &ev );
|
if ( ev.type == KeyPress ) handle_keypress( &ev );
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
80
textbox.c
80
textbox.c
|
@ -56,9 +56,13 @@ textbox* textbox_create(Window parent, unsigned long flags, short x, short y, sh
|
||||||
tb->flags = flags;
|
tb->flags = flags;
|
||||||
tb->parent = parent;
|
tb->parent = parent;
|
||||||
|
|
||||||
tb->x = x; tb->y = y; tb->w = MAX(1, w); tb->h = MAX(1, h);
|
tb->x = x;
|
||||||
|
tb->y = y;
|
||||||
|
tb->w = MAX( 1, w );
|
||||||
|
tb->h = MAX( 1, h );
|
||||||
|
|
||||||
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
XColor color;
|
||||||
|
Colormap map = DefaultColormap( display, DefaultScreen( display ) );
|
||||||
unsigned int cp = XAllocNamedColor( display, map, bg, &color, &color ) ? color.pixel: None;
|
unsigned int cp = XAllocNamedColor( display, map, bg, &color, &color ) ? color.pixel: None;
|
||||||
|
|
||||||
tb->window = XCreateSimpleWindow( display, tb->parent, tb->x, tb->y, tb->w, tb->h, 0, None, cp );
|
tb->window = XCreateSimpleWindow( display, tb->parent, tb->x, tb->y, tb->w, tb->h, 0, None, cp );
|
||||||
|
@ -73,8 +77,7 @@ textbox* textbox_create(Window parent, unsigned long flags, short x, short y, sh
|
||||||
textbox_moveresize( tb, tb->x, tb->y, tb->w, tb->h );
|
textbox_moveresize( tb, tb->x, tb->y, tb->w, tb->h );
|
||||||
|
|
||||||
// edit mode controls
|
// edit mode controls
|
||||||
if (tb->flags & TB_EDITABLE)
|
if ( tb->flags & TB_EDITABLE ) {
|
||||||
{
|
|
||||||
tb->xim = XOpenIM( display, NULL, NULL, NULL );
|
tb->xim = XOpenIM( display, NULL, NULL, NULL );
|
||||||
tb->xic = XCreateIC( tb->xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, tb->window, XNFocusWindow, tb->window, NULL );
|
tb->xic = XCreateIC( tb->xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, tb->window, XNFocusWindow, tb->window, NULL );
|
||||||
}
|
}
|
||||||
|
@ -86,6 +89,7 @@ textbox* textbox_create(Window parent, unsigned long flags, short x, short y, sh
|
||||||
void textbox_font( textbox *tb, char *font, char *fg, char *bg )
|
void textbox_font( textbox *tb, char *font, char *fg, char *bg )
|
||||||
{
|
{
|
||||||
if ( tb->font ) XftFontClose( display, tb->font );
|
if ( tb->font ) XftFontClose( display, tb->font );
|
||||||
|
|
||||||
tb->font = XftFontOpenName( display, DefaultScreen( display ), font );
|
tb->font = XftFontOpenName( display, DefaultScreen( display ), font );
|
||||||
|
|
||||||
XftColorAllocName( display, DefaultVisual( display, DefaultScreen( display ) ), DefaultColormap( display, DefaultScreen( display ) ), fg, &tb->color_fg );
|
XftColorAllocName( display, DefaultVisual( display, DefaultScreen( display ) ), DefaultColormap( display, DefaultScreen( display ) ), fg, &tb->color_fg );
|
||||||
|
@ -105,6 +109,7 @@ void textbox_extents(textbox *tb)
|
||||||
void textbox_text( textbox *tb, char *text )
|
void textbox_text( textbox *tb, char *text )
|
||||||
{
|
{
|
||||||
if ( tb->text ) free( tb->text );
|
if ( tb->text ) free( tb->text );
|
||||||
|
|
||||||
tb->text = strdup( text );
|
tb->text = strdup( text );
|
||||||
tb->cursor = MAX( 0,MIN( ( int )strlen( text ), tb->cursor ) );
|
tb->cursor = MAX( 0,MIN( ( int )strlen( text ), tb->cursor ) );
|
||||||
textbox_extents( tb );
|
textbox_extents( tb );
|
||||||
|
@ -114,6 +119,7 @@ void textbox_text(textbox *tb, char *text)
|
||||||
void textbox_prompt( textbox *tb, char *text )
|
void textbox_prompt( textbox *tb, char *text )
|
||||||
{
|
{
|
||||||
if ( tb->prompt ) free( tb->prompt );
|
if ( tb->prompt ) free( tb->prompt );
|
||||||
|
|
||||||
tb->prompt = strdup( text );
|
tb->prompt = strdup( text );
|
||||||
textbox_extents( tb );
|
textbox_extents( tb );
|
||||||
}
|
}
|
||||||
|
@ -127,9 +133,11 @@ void textbox_moveresize(textbox *tb, int x, int y, int w, int h)
|
||||||
if ( tb->flags & TB_AUTOWIDTH )
|
if ( tb->flags & TB_AUTOWIDTH )
|
||||||
w = tb->extents.width;
|
w = tb->extents.width;
|
||||||
|
|
||||||
if (x != tb->x || y != tb->y || w != tb->w || h != tb->h)
|
if ( x != tb->x || y != tb->y || w != tb->w || h != tb->h ) {
|
||||||
{
|
tb->x = x;
|
||||||
tb->x = x; tb->y = y; tb->w = MAX(1, w); tb->h = MAX(1, h);
|
tb->y = y;
|
||||||
|
tb->w = MAX( 1, w );
|
||||||
|
tb->h = MAX( 1, h );
|
||||||
XMoveResizeWindow( display, tb->window, tb->x, tb->y, tb->w, tb->h );
|
XMoveResizeWindow( display, tb->window, tb->x, tb->y, tb->w, tb->h );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,14 +155,15 @@ void textbox_hide(textbox *tb)
|
||||||
// will also unmap the window if still displayed
|
// will also unmap the window if still displayed
|
||||||
void textbox_free( textbox *tb )
|
void textbox_free( textbox *tb )
|
||||||
{
|
{
|
||||||
if (tb->flags & TB_EDITABLE)
|
if ( tb->flags & TB_EDITABLE ) {
|
||||||
{
|
|
||||||
XDestroyIC( tb->xic );
|
XDestroyIC( tb->xic );
|
||||||
XCloseIM( tb->xim );
|
XCloseIM( tb->xim );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tb->text ) free( tb->text );
|
if ( tb->text ) free( tb->text );
|
||||||
|
|
||||||
if ( tb->prompt ) free( tb->prompt );
|
if ( tb->prompt ) free( tb->prompt );
|
||||||
|
|
||||||
if ( tb->font ) XftFontClose( display, tb->font );
|
if ( tb->font ) XftFontClose( display, tb->font );
|
||||||
|
|
||||||
XDestroyWindow( display, tb->window );
|
XDestroyWindow( display, tb->window );
|
||||||
|
@ -186,8 +195,7 @@ void textbox_draw(textbox *tb)
|
||||||
int cursor_offset = 0;
|
int cursor_offset = 0;
|
||||||
int cursor_width = MAX( 2, line_height/10 );
|
int cursor_width = MAX( 2, line_height/10 );
|
||||||
|
|
||||||
if (tb->flags & TB_EDITABLE)
|
if ( tb->flags & TB_EDITABLE ) {
|
||||||
{
|
|
||||||
int prompt_len = strlen( prompt );
|
int prompt_len = strlen( prompt );
|
||||||
length = text_len + prompt_len;
|
length = text_len + prompt_len;
|
||||||
cursor_offset = MIN( tb->cursor + prompt_len, length );
|
cursor_offset = MIN( tb->cursor + prompt_len, length );
|
||||||
|
@ -211,7 +219,9 @@ void textbox_draw(textbox *tb)
|
||||||
line_width = extents.width;
|
line_width = extents.width;
|
||||||
|
|
||||||
int x = 2, y = tb->font->ascent;
|
int x = 2, y = tb->font->ascent;
|
||||||
|
|
||||||
if ( tb->flags & TB_RIGHT ) x = tb->w - line_width;
|
if ( tb->flags & TB_RIGHT ) x = tb->w - line_width;
|
||||||
|
|
||||||
if ( tb->flags & TB_CENTER ) x = ( tb->w - line_width ) / 2;
|
if ( tb->flags & TB_CENTER ) x = ( tb->w - line_width ) / 2;
|
||||||
|
|
||||||
// draw the text, including any prompt in edit mode
|
// draw the text, including any prompt in edit mode
|
||||||
|
@ -302,8 +312,7 @@ void textbox_cursor_del(textbox *tb)
|
||||||
// back up and delete one character
|
// back up and delete one character
|
||||||
void textbox_cursor_bkspc( textbox *tb )
|
void textbox_cursor_bkspc( textbox *tb )
|
||||||
{
|
{
|
||||||
if (tb->cursor > 0)
|
if ( tb->cursor > 0 ) {
|
||||||
{
|
|
||||||
textbox_cursor_dec( tb );
|
textbox_cursor_dec( tb );
|
||||||
textbox_cursor_del( tb );
|
textbox_cursor_del( tb );
|
||||||
}
|
}
|
||||||
|
@ -315,60 +324,41 @@ void textbox_cursor_bkspc(textbox *tb)
|
||||||
// -1 = handled and return pressed (finished)
|
// -1 = handled and return pressed (finished)
|
||||||
int textbox_keypress( textbox *tb, XEvent *ev )
|
int textbox_keypress( textbox *tb, XEvent *ev )
|
||||||
{
|
{
|
||||||
KeySym key; Status stat;
|
KeySym key;
|
||||||
char pad[32]; int len;
|
Status stat;
|
||||||
|
char pad[32];
|
||||||
|
int len;
|
||||||
|
|
||||||
if ( !( tb->flags & TB_EDITABLE ) ) return 0;
|
if ( !( tb->flags & TB_EDITABLE ) ) return 0;
|
||||||
|
|
||||||
len = XmbLookupString( tb->xic, &ev->xkey, pad, sizeof( pad ), &key, &stat );
|
len = XmbLookupString( tb->xic, &ev->xkey, pad, sizeof( pad ), &key, &stat );
|
||||||
pad[len] = 0;
|
pad[len] = 0;
|
||||||
|
|
||||||
if (key == XK_Left)
|
if ( key == XK_Left ) {
|
||||||
{
|
|
||||||
textbox_cursor_dec( tb );
|
textbox_cursor_dec( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_Right ) {
|
||||||
else
|
|
||||||
if (key == XK_Right)
|
|
||||||
{
|
|
||||||
textbox_cursor_inc( tb );
|
textbox_cursor_inc( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_Home ) {
|
||||||
else
|
|
||||||
if (key == XK_Home)
|
|
||||||
{
|
|
||||||
textbox_cursor_home( tb );
|
textbox_cursor_home( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_End ) {
|
||||||
else
|
|
||||||
if (key == XK_End)
|
|
||||||
{
|
|
||||||
textbox_cursor_end( tb );
|
textbox_cursor_end( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_Delete ) {
|
||||||
else
|
|
||||||
if (key == XK_Delete)
|
|
||||||
{
|
|
||||||
textbox_cursor_del( tb );
|
textbox_cursor_del( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_BackSpace ) {
|
||||||
else
|
|
||||||
if (key == XK_BackSpace)
|
|
||||||
{
|
|
||||||
textbox_cursor_bkspc( tb );
|
textbox_cursor_bkspc( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if ( key == XK_Return ) {
|
||||||
else
|
|
||||||
if (key == XK_Return)
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if ( !iscntrl( *pad ) ) {
|
||||||
else
|
|
||||||
if (!iscntrl(*pad))
|
|
||||||
{
|
|
||||||
textbox_insert( tb, tb->cursor, pad );
|
textbox_insert( tb, tb->cursor, pad );
|
||||||
textbox_cursor_inc( tb );
|
textbox_cursor_inc( tb );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue