logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

0003-Add-support-for-plumbing-via-right-click.patch (3818B)


  1. From 85a6bb6ba81de493c0ceb9a8d4c2f78eb5d1567f Mon Sep 17 00:00:00 2001
  2. From: Michael Forney <mforney@mforney.org>
  3. Date: Wed, 2 Dec 2020 17:54:35 -0800
  4. Subject: [PATCH] Add support for plumbing via right click
  5. ---
  6. config.def.h | 5 ++++
  7. st.c | 79 ++++++++++++++++++++++++++++++++++++++++++++--------
  8. 2 files changed, 72 insertions(+), 12 deletions(-)
  9. diff --git a/config.def.h b/config.def.h
  10. index 49ca50b..a63d2be 100644
  11. --- a/config.def.h
  12. +++ b/config.def.h
  13. @@ -460,3 +460,8 @@ static char ascii_printable[] =
  14. "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
  15. "`abcdefghijklmnopqrstuvwxyz{|}~";
  16. +/*
  17. + * plumb_cmd is run on mouse button 3 click, with first NULL set to
  18. + * current selection and with cwd set to the cwd of the active shell
  19. + */
  20. +static char *plumb_cmd[] = {"plumb", NULL, NULL};
  21. diff --git a/st.c b/st.c
  22. index 20a3c3c..914fdd5 100644
  23. --- a/st.c
  24. +++ b/st.c
  25. @@ -44,6 +44,9 @@ char *argv0;
  26. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  27. #include <libutil.h>
  28. #endif
  29. +#if defined(__OpenBSD__)
  30. + #include <sys/sysctl.h>
  31. +#endif
  32. /* Arbitrary sizes */
  33. @@ -558,6 +561,8 @@ static void *xmalloc(size_t);
  34. static void *xrealloc(void *, size_t);
  35. static char *xstrdup(char *);
  36. +static int subprocwd(char *, size_t);
  37. +
  38. static void usage(void);
  39. static struct wl_registry_listener reglistener = { regglobal, regglobalremove };
  40. @@ -579,6 +584,7 @@ static struct wl_data_source_listener datasrclistener =
  41. { datasrctarget, datasrcsend, datasrccancelled };
  42. /* Globals */
  43. +static int plumbsel;
  44. static DC dc;
  45. static Wayland wl;
  46. static WLD wld;
  47. @@ -763,6 +769,21 @@ utf8validate(Rune *u, size_t i)
  48. return i;
  49. }
  50. +int
  51. +subprocwd(char *path, size_t len)
  52. +{
  53. +#if defined(__linux__)
  54. + if (snprintf(path, len, "/proc/%d/cwd", pid) < 0)
  55. + return -1;
  56. + return 0;
  57. +#elif defined(__OpenBSD__)
  58. + int name[3] = {CTL_KERN, KERN_PROC_CWD, pid};
  59. + if (sysctl(name, 3, path, &len, 0, 0) == -1)
  60. + return -1;
  61. + return 0;
  62. +#endif
  63. +}
  64. +
  65. void
  66. selinit(void)
  67. {
  68. @@ -1165,6 +1186,29 @@ wlsetsel(char *str, uint32_t serial)
  69. wl_data_device_set_selection(wl.datadev, sel.source, serial);
  70. }
  71. +void
  72. +plumbinit(void)
  73. +{
  74. + for (plumbsel = 0; plumb_cmd[plumbsel]; ++plumbsel)
  75. + ;
  76. +}
  77. +
  78. +void
  79. +plumb(char *sel)
  80. +{
  81. + char cwd[PATH_MAX];
  82. +
  83. + if (!sel || subprocwd(cwd, sizeof(cwd)) != 0)
  84. + return;
  85. + plumb_cmd[plumbsel] = sel;
  86. +
  87. + if (fork() == 0) {
  88. + if (chdir(cwd) == 0)
  89. + execvp(plumb_cmd[0], plumb_cmd);
  90. + _exit(1);
  91. + }
  92. +}
  93. +
  94. void
  95. die(const char *errstr, ...)
  96. {
  97. @@ -1227,15 +1271,18 @@ sigchld(int a)
  98. int stat;
  99. pid_t p;
  100. - if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
  101. - die("Waiting for pid %hd failed: %s\n", pid, strerror(errno));
  102. -
  103. - if (pid != p)
  104. - return;
  105. -
  106. - if (!WIFEXITED(stat) || WEXITSTATUS(stat))
  107. - die("child finished with error '%d'\n", stat);
  108. - exit(0);
  109. + for (;;) {
  110. + p = waitpid(-1, &stat, WNOHANG);
  111. + if (p == 0)
  112. + break;
  113. + if (p < 0)
  114. + die("waitpid: %s\n", strerror(errno));
  115. + if (pid == p) {
  116. + if (!WIFEXITED(stat) || WEXITSTATUS(stat))
  117. + die("child finished with error '%d'\n", stat);
  118. + exit(0);
  119. + }
  120. + }
  121. }
  122. @@ -4224,16 +4271,23 @@ ptrbutton(void * data, struct wl_pointer * pointer, uint32_t serial,
  123. switch (state) {
  124. case WL_POINTER_BUTTON_STATE_RELEASED:
  125. - if (button == BTN_MIDDLE) {
  126. + switch (button) {
  127. + case BTN_MIDDLE:
  128. selpaste(NULL);
  129. - } else if (button == BTN_LEFT) {
  130. + break;
  131. + case BTN_LEFT:
  132. if (sel.mode == SEL_READY) {
  133. getbuttoninfo();
  134. selcopy(serial);
  135. - } else
  136. + } else {
  137. selclear();
  138. + }
  139. sel.mode = SEL_IDLE;
  140. tsetdirt(sel.nb.y, sel.ne.y);
  141. + break;
  142. + case BTN_RIGHT:
  143. + plumb(sel.primary);
  144. + break;
  145. }
  146. break;
  147. @@ -4557,6 +4611,7 @@ main(int argc, char *argv[])
  148. } ARGEND;
  149. run:
  150. + plumbinit();
  151. if (argc > 0) {
  152. /* eat all remaining arguments */
  153. opt_cmd = argv;
  154. --
  155. 2.37.3