@@ -48,7 +48,7 @@ static int oflag = 0; /* whether only one notification must exist at a time */
48
48
void
49
49
usage (void )
50
50
{
51
- (void )fprintf (stderr , "usage: xnotify [-o] [-G gravity] [-g geometry] [-m monitor] [-s seconds]\n" );
51
+ (void )fprintf (stderr , "usage: xnotify [-o] [-G gravity] [-b button] [- g geometry] [-m monitor] [-s seconds]\n" );
52
52
exit (1 );
53
53
}
54
54
@@ -111,11 +111,34 @@ getoptions(int argc, char *argv[])
111
111
unsigned long n ;
112
112
int ch ;
113
113
114
- while ((ch = getopt (argc , argv , "G:g:m:os:" )) != -1 ) {
114
+ while ((ch = getopt (argc , argv , "G:b: g:m:os:" )) != -1 ) {
115
115
switch (ch ) {
116
116
case 'G' :
117
117
config .gravityspec = optarg ;
118
118
break ;
119
+ case 'b' :
120
+ if (* (optarg + 1 ) != '\0' )
121
+ break ;
122
+ switch (* optarg ) {
123
+ case '1' :
124
+ config .actionbutton = Button1 ;
125
+ break ;
126
+ case '2' :
127
+ config .actionbutton = Button2 ;
128
+ break ;
129
+ case '3' :
130
+ config .actionbutton = Button3 ;
131
+ break ;
132
+ case '4' :
133
+ config .actionbutton = Button4 ;
134
+ break ;
135
+ case '5' :
136
+ config .actionbutton = Button5 ;
137
+ break ;
138
+ default :
139
+ break ;
140
+ }
141
+ break ;
119
142
case 'g' :
120
143
config .geometryspec = optarg ;
121
144
break ;
@@ -731,7 +754,7 @@ resettime(struct Item *item)
731
754
732
755
/* add item notification item and set its window and contents */
733
756
static void
734
- additem (struct Queue * queue , const char * title , const char * body , const char * file , const char * background , const char * foreground , const char * border )
757
+ additem (struct Queue * queue , struct Itemspec * itemspec )
735
758
{
736
759
struct Item * item ;
737
760
int titlew , bodyw ;
@@ -740,9 +763,11 @@ additem(struct Queue *queue, const char *title, const char *body, const char *fi
740
763
if ((item = malloc (sizeof * item )) == NULL )
741
764
err (1 , "malloc" );
742
765
item -> next = NULL ;
743
- item -> title = strdup (title );
744
- item -> body = (body ) ? strdup (body ) : NULL ;
745
- item -> image = (file ) ? loadimage (file ) : NULL ;
766
+ item -> title = strdup (itemspec -> title );
767
+ item -> body = (itemspec -> body ) ? strdup (itemspec -> body ) : NULL ;
768
+ item -> image = (itemspec -> file ) ? loadimage (itemspec -> file ) : NULL ;
769
+ item -> tag = (itemspec -> tag ) ? strdup (itemspec -> tag ) : NULL ;
770
+ item -> cmd = (itemspec -> cmd ) ? strdup (itemspec -> cmd ) : NULL ;
746
771
if (!queue -> head )
747
772
queue -> head = item ;
748
773
else
@@ -751,11 +776,11 @@ additem(struct Queue *queue, const char *title, const char *body, const char *fi
751
776
queue -> tail = item ;
752
777
753
778
/* allocate colors */
754
- if (!background || ealloccolor (background , & item -> background , 0 ) == -1 )
779
+ if (!itemspec -> background || ealloccolor (itemspec -> background , & item -> background , 0 ) == -1 )
755
780
item -> background = dc .background ;
756
- if (!foreground || ealloccolor (foreground , & item -> foreground , 0 ) == -1 )
781
+ if (!itemspec -> foreground || ealloccolor (itemspec -> foreground , & item -> foreground , 0 ) == -1 )
757
782
item -> foreground = dc .foreground ;
758
- if (!border || ealloccolor (border , & item -> border , 0 ) == -1 )
783
+ if (!itemspec -> border || ealloccolor (itemspec -> border , & item -> border , 0 ) == -1 )
759
784
item -> border = dc .border ;
760
785
761
786
/* compute notification height */
@@ -824,73 +849,72 @@ optiontype(const char *s)
824
849
return FG ;
825
850
if (strncmp (s , "BRD:" , 4 ) == 0 )
826
851
return BRD ;
852
+ if (strncmp (s , "TAG:" , 4 ) == 0 )
853
+ return TAG ;
854
+ if (strncmp (s , "CMD:" , 4 ) == 0 )
855
+ return CMD ;
827
856
return UNKNOWN ;
828
857
}
829
858
830
- /* destroy all notification items */
831
- static void
832
- cleanitems (struct Queue * queue )
833
- {
834
- struct Item * item ;
835
- struct Item * tmp ;
836
-
837
- item = queue -> head ;
838
- while (item ) {
839
- tmp = item ;
840
- item = item -> next ;
841
- delitem (queue , tmp );
842
- }
843
- }
844
-
845
- /* read stdin */
846
- static void
847
- parseinput (struct Queue * queue , char * s )
859
+ /* parse notification line */
860
+ static struct Itemspec *
861
+ parseline (char * s )
848
862
{
849
863
enum ItemOption option ;
850
- char * title , * body , * file , * fg , * bg , * brd ;
864
+ struct Itemspec * itemspec ;
865
+
866
+ if ((itemspec = malloc (sizeof * itemspec )) == NULL )
867
+ err (1 , "malloc" );
851
868
852
869
/* get the title */
853
- title = strtok (s , "\t\n" );
870
+ itemspec -> title = strtok (s , "\t\n" );
854
871
855
872
/* get the filename */
856
- file = NULL ;
857
- fg = bg = brd = NULL ;
858
- while (title && (option = optiontype (title )) != UNKNOWN ) {
873
+ itemspec -> file = NULL ;
874
+ itemspec -> foreground = NULL ;
875
+ itemspec -> background = NULL ;
876
+ itemspec -> border = NULL ;
877
+ itemspec -> tag = NULL ;
878
+ itemspec -> cmd = NULL ;
879
+ while (itemspec -> title && (option = optiontype (itemspec -> title )) != UNKNOWN ) {
859
880
switch (option ) {
860
881
case IMG :
861
- file = title + 4 ;
862
- title = strtok (NULL , "\t\n" );
882
+ itemspec -> file = itemspec -> title + 4 ;
883
+ itemspec -> title = strtok (NULL , "\t\n" );
863
884
break ;
864
885
case BG :
865
- bg = title + 3 ;
866
- title = strtok (NULL , "\t\n" );
886
+ itemspec -> background = itemspec -> title + 3 ;
887
+ itemspec -> title = strtok (NULL , "\t\n" );
867
888
break ;
868
889
case FG :
869
- fg = title + 3 ;
870
- title = strtok (NULL , "\t\n" );
890
+ itemspec -> foreground = itemspec -> title + 3 ;
891
+ itemspec -> title = strtok (NULL , "\t\n" );
871
892
break ;
872
893
case BRD :
873
- brd = title + 4 ;
874
- title = strtok (NULL , "\t\n" );
894
+ itemspec -> border = itemspec -> title + 4 ;
895
+ itemspec -> title = strtok (NULL , "\t\n" );
875
896
break ;
897
+ case TAG :
898
+ itemspec -> tag = itemspec -> title + 4 ;
899
+ itemspec -> title = strtok (NULL , "\t\n" );
900
+ case CMD :
901
+ itemspec -> cmd = itemspec -> title + 4 ;
902
+ itemspec -> title = strtok (NULL , "\t\n" );
876
903
default :
877
904
break ;
878
905
}
879
906
}
880
907
881
908
/* get the body */
882
- body = strtok (NULL , "\n" );
883
- if (body )
884
- while (* body == '\t' )
885
- body ++ ;
909
+ itemspec -> body = strtok (NULL , "\n" );
910
+ if (itemspec -> body )
911
+ while (* itemspec -> body == '\t' )
912
+ itemspec -> body ++ ;
886
913
887
- if (!title )
888
- return ;
889
-
890
- if (oflag )
891
- cleanitems (queue );
914
+ if (!itemspec -> title )
915
+ return NULL ;
892
916
893
- additem ( queue , title , body , file , bg , fg , brd ) ;
917
+ return itemspec ;
894
918
}
895
919
896
920
/* read x events */
@@ -907,8 +931,11 @@ readevent(struct Queue *queue)
907
931
copypixmap (item );
908
932
break ;
909
933
case ButtonPress :
910
- if ((item = getitem (queue , ev .xexpose .window )) != NULL )
911
- delitem (queue , item );
934
+ if ((item = getitem (queue , ev .xbutton .window )) == NULL )
935
+ break ;
936
+ if ((ev .xbutton .button == config .actionbutton ) && item -> cmd )
937
+ printf ("%s\n" , item -> cmd );
938
+ delitem (queue , item );
912
939
break ;
913
940
case MotionNotify :
914
941
if ((item = getitem (queue , ev .xmotion .window )) != NULL )
@@ -998,6 +1025,23 @@ moveitems(struct Queue *queue)
998
1025
queue -> change = 0 ;
999
1026
}
1000
1027
1028
+ /* destroy all notification items of the given tag, or all items if tag is NULL */
1029
+ static void
1030
+ cleanitems (struct Queue * queue , const char * tag )
1031
+ {
1032
+ struct Item * item ;
1033
+ struct Item * tmp ;
1034
+
1035
+ item = queue -> head ;
1036
+ while (item ) {
1037
+ tmp = item ;
1038
+ item = item -> next ;
1039
+ if (tag == NULL || (tmp -> tag && strcmp (tmp -> tag , tag ) == 0 )) {
1040
+ delitem (queue , tmp );
1041
+ }
1042
+ }
1043
+ }
1044
+
1001
1045
/* clean up dc elements */
1002
1046
static void
1003
1047
cleandc (void )
@@ -1015,6 +1059,7 @@ cleandc(void)
1015
1059
int
1016
1060
main (int argc , char * argv [])
1017
1061
{
1062
+ struct Itemspec * itemspec ;
1018
1063
struct Queue * queue ; /* it contains the queue of notifications and their geometry */
1019
1064
struct pollfd pfd [2 ]; /* [2] for stdin and xfd, see poll(2) */
1020
1065
char buf [BUFSIZ ]; /* buffer for stdin */
@@ -1076,7 +1121,14 @@ main(int argc, char *argv[])
1076
1121
if (pfd [0 ].revents & POLLIN ) {
1077
1122
if (fgets (buf , sizeof buf , stdin ) == NULL )
1078
1123
break ;
1079
- parseinput (queue , buf );
1124
+ if ((itemspec = parseline (buf )) != NULL ) {
1125
+ if (oflag ) {
1126
+ cleanitems (queue , NULL );
1127
+ } else if (itemspec -> tag ) {
1128
+ cleanitems (queue , itemspec -> tag );
1129
+ }
1130
+ additem (queue , itemspec );
1131
+ }
1080
1132
}
1081
1133
if (pfd [1 ].revents & POLLIN ) {
1082
1134
readevent (queue );
@@ -1093,7 +1145,7 @@ main(int argc, char *argv[])
1093
1145
}
1094
1146
1095
1147
/* clean up stuff */
1096
- cleanitems (queue );
1148
+ cleanitems (queue , NULL );
1097
1149
cleandc ();
1098
1150
free (queue );
1099
1151
0 commit comments