@@ -319,6 +319,79 @@ parse_bind(const char *bind, struct config_action *action) {
319319 return 0 ;
320320}
321321
322+ static int
323+ parse_ninb_anchor (const char * input , struct config_ninb * out ) {
324+ static const char * anchor_names [] = {
325+ [ANCHOR_TOPLEFT ] = "topleft" ,
326+ [ANCHOR_TOP ] = "top" ,
327+ [ANCHOR_TOPRIGHT ] = "topright" ,
328+ [ANCHOR_LEFT ] = "left" ,
329+ [ANCHOR_RIGHT ] = "right" ,
330+ [ANCHOR_BOTTOMLEFT ] = "bottomleft" ,
331+ [ANCHOR_BOTTOMRIGHT ] = "bottomright" ,
332+ };
333+
334+ str ninb_anchor = str_from (input );
335+ ssize_t len = str_index (ninb_anchor , '+' , 0 );
336+ if (len == -1 ) {
337+ len = ninb_anchor .len ;
338+ }
339+ bool has_offset = len != ninb_anchor .len ;
340+
341+ for (size_t i = 0 ; i < STATIC_ARRLEN (anchor_names ); i ++ ) {
342+ if (strncasecmp (anchor_names [i ], input , len ) == 0 ) {
343+ out -> anchor = i ;
344+
345+ if (!has_offset ) {
346+ return 0 ;
347+ }
348+
349+ if (str_index (ninb_anchor , '(' , len ) != len + 1 ) {
350+ goto invalid_offset ;
351+ }
352+ if (str_index (ninb_anchor , ')' , len ) != ninb_anchor .len - 1 ) {
353+ goto invalid_offset ;
354+ }
355+
356+ str offset_inner = str_slice (ninb_anchor , len + 2 , ninb_anchor .len - 1 );
357+ struct str_halves halves = str_halves (offset_inner , ',' );
358+
359+ if (halves .a .len == 0 || halves .b .len == 0 ) {
360+ goto invalid_offset ;
361+ }
362+
363+ char * endptr ;
364+ long x = strtol (halves .a .data , & endptr , 10 );
365+ if (endptr == halves .a .data || * endptr != ',' ) {
366+ goto invalid_offset ;
367+ }
368+ if (x < INT32_MIN || x > INT32_MAX ) {
369+ goto invalid_offset ;
370+ }
371+
372+ long y = strtol (halves .b .data , & endptr , 10 );
373+ if (endptr == halves .b .data || endptr != ninb_anchor .data + ninb_anchor .len - 1 ) {
374+ goto invalid_offset ;
375+ }
376+ if (y < INT32_MIN || y > INT32_MAX ) {
377+ goto invalid_offset ;
378+ }
379+
380+ out -> offset_x = x ;
381+ out -> offset_y = y ;
382+
383+ return 0 ;
384+ }
385+ }
386+
387+ ww_log (LOG_ERROR , "invalid value '%s' for 'theme.ninb_anchor'" , input );
388+ return 1 ;
389+
390+ invalid_offset :
391+ ww_log (LOG_ERROR , "invalid offset in value '%s' for 'theme.ninb_anchor'" , input );
392+ return 1 ;
393+ }
394+
322395static int
323396parse_remap_half (const char * input , uint32_t * out_data , enum config_remap_type * out_type ) {
324397 for (size_t i = 0 ; i < STATIC_ARRLEN (util_keycodes ); i ++ ) {
@@ -672,30 +745,12 @@ process_config_theme(struct config *cfg) {
672745 return 1 ;
673746 }
674747 if (ninb_anchor ) {
675- static const char * anchor_names [] = {
676- [ANCHOR_TOPLEFT ] = "topleft" ,
677- [ANCHOR_TOP ] = "top" ,
678- [ANCHOR_TOPRIGHT ] = "topright" ,
679- [ANCHOR_LEFT ] = "left" ,
680- [ANCHOR_RIGHT ] = "right" ,
681- [ANCHOR_BOTTOMLEFT ] = "bottomleft" ,
682- [ANCHOR_BOTTOMRIGHT ] = "bottomright" ,
683- };
684-
685- for (size_t i = 0 ; i < STATIC_ARRLEN (anchor_names ); i ++ ) {
686- if (strcasecmp (anchor_names [i ], ninb_anchor ) == 0 ) {
687- cfg -> theme .ninb .anchor = i ;
688- break ;
689- }
690- }
691-
692- if (cfg -> theme .ninb .anchor == ANCHOR_NONE ) {
693- ww_log (LOG_ERROR , "invalid value '%s' for 'theme.ninb_anchor'" , ninb_anchor );
694- free (ninb_anchor );
748+ int ret = parse_ninb_anchor (ninb_anchor , & cfg -> theme .ninb );
749+ free (ninb_anchor );
750+ if (ret != 0 ) {
695751 return 1 ;
696752 }
697753 }
698- free (ninb_anchor );
699754
700755 if (get_double (cfg , "ninb_opacity" , & cfg -> theme .ninb .opacity , "theme.ninb_opacity" , false) !=
701756 0 ) {
0 commit comments