commit 7615c2f0aaf93aa54ee3b5cbe43abcf83684ffd1
parent 35e6403c69410f8be6880c1d554ded5a3afb1c4d
Author: bakkeby <bakkeby@gmail.com>
Date: Mon, 16 Sep 2019 12:40:07 +0200
Adding fixime, newterm and opencopied patches
Diffstat:
17 files changed, 255 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
@@ -11,7 +11,7 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th
### Changelog:
-2019-09-16 - Added alpha, anysize, bold-is-not-bright, clipboard, copyurl and disable-fonts patches
+2019-09-16 - Added alpha, anysize, bold-is-not-bright, clipboard, copyurl, disable-fonts, fixime, hidecursor, newterm and open-copied-url patches
### Patches included:
@@ -34,4 +34,17 @@ Refer to [https://dwm.suckless.org/](https://st.suckless.org/) for details on th
- multiple invocations cycle through the available URLs
- [disable-fonts](https://st.suckless.org/patches/disable_bold_italic_fonts/)
- - this patch adds the option of disabling bold/italic/roman fonts globally
-\ No newline at end of file
+ - this patch adds the option of disabling bold/italic/roman fonts globally
+
+ - [fixime](https://st.suckless.org/patches/fix_ime/)
+ - adds better Input Method Editor (IME) support
+
+ - [hidecursor](https://st.suckless.org/patches/hidecursor/)
+ - hides the X cursor whenever a key is pressed and show it back when the mouse is moved in the terminal window
+
+ - [newterm](https://st.suckless.org/patches/newterm/)
+ - allows you to spawn a new st terminal using Ctrl-Shift-Return
+ - it will have the same CWD (current working directory) as the original st instance
+
+ - [open-copied-url](https://st.suckless.org/patches/open_copied_url/)
+ - open contents of the clipboard in a user-defined browser
+\ No newline at end of file
diff --git a/config.def.h b/config.def.h
@@ -198,6 +198,12 @@ static Shortcut shortcuts[] = {
#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
{ MODKEY, XK_l, copyurl, {.i = 0} },
#endif // COPYURL_PATCH
+ #if OPENCOPIED_PATCH
+ { MODKEY, XK_o, opencopied, {.v = "xdg-open"} },
+ #endif // OPENCOPIED_PATCH
+ #if NEWTERM_PATCH
+ { TERMMOD, XK_Return, newterm, {.i = 0} },
+ #endif // NEWTERM_PATCH
};
/*
diff --git a/patch/fixime.c b/patch/fixime.c
@@ -0,0 +1,49 @@
+void
+ximopen(Display *dpy)
+{
+ XIMCallback destroy = { .client_data = NULL, .callback = ximdestroy };
+
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ XSetLocaleModifiers("@im=local");
+ if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
+ XSetLocaleModifiers("@im=");
+ if ((xw.xim = XOpenIM(xw.dpy,
+ NULL, NULL, NULL)) == NULL) {
+ die("XOpenIM failed. Could not open input"
+ " device.\n");
+ }
+ }
+ }
+ if (XSetIMValues(xw.xim, XNDestroyCallback, &destroy, NULL) != NULL)
+ die("XSetIMValues failed. Could not set input method value.\n");
+ xw.xic = XCreateIC(xw.xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow, xw.win, XNFocusWindow, xw.win, NULL);
+ if (xw.xic == NULL)
+ die("XCreateIC failed. Could not obtain input method.\n");
+}
+
+void
+ximinstantiate(Display *dpy, XPointer client, XPointer call)
+{
+ ximopen(dpy);
+ XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
+ ximinstantiate, NULL);
+}
+
+void
+ximdestroy(XIM xim, XPointer client, XPointer call)
+{
+ xw.xim = NULL;
+ XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL,
+ ximinstantiate, NULL);
+}
+
+void
+xximspot(int x, int y)
+{
+ XPoint spot = { borderpx + x * win.cw, borderpx + (y + 1) * win.ch };
+ XVaNestedList attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
+
+ XSetICValues(xw.xic, XNPreeditAttributes, attr, NULL);
+ XFree(attr);
+}
+\ No newline at end of file
diff --git a/patch/fixime.h b/patch/fixime.h
@@ -0,0 +1,4 @@
+static void ximopen(Display *);
+static void ximinstantiate(Display *, XPointer, XPointer);
+static void ximdestroy(XIM, XPointer, XPointer);
+void xximspot(int, int);
+\ No newline at end of file
diff --git a/patch/include.c b/patch/include.c
@@ -1,5 +0,0 @@
-/* Patches */
-
-#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
-#include "copyurl.c"
-#endif
-\ No newline at end of file
diff --git a/patch/include.h b/patch/include.h
@@ -1,5 +0,0 @@
-/* Patches */
-
-#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
-#include "copyurl.h"
-#endif
-\ No newline at end of file
diff --git a/patch/newterm.c b/patch/newterm.c
@@ -0,0 +1,20 @@
+void
+newterm(const Arg* a)
+{
+ int res;
+ switch (fork()) {
+ case -1:
+ die("fork failed: %s\n", strerror(errno));
+ break;
+ case 0:
+ res = chdir(getcwd_by_pid(pid));
+ execlp("st", "./st", NULL);
+ break;
+ }
+}
+
+static char *getcwd_by_pid(pid_t pid) {
+ char buf[32];
+ snprintf(buf, sizeof buf, "/proc/%d/cwd", pid);
+ return realpath(buf, NULL);
+}
+\ No newline at end of file
diff --git a/patch/newterm.h b/patch/newterm.h
@@ -0,0 +1,2 @@
+void newterm(const Arg *);
+static char *getcwd_by_pid(pid_t pid);
+\ No newline at end of file
diff --git a/patch/opencopied.c b/patch/opencopied.c
@@ -0,0 +1,19 @@
+void
+opencopied(const Arg *arg)
+{
+ int res;
+ size_t const max_cmd = 2048;
+ char * const clip = xsel.clipboard;
+ if (!clip) {
+ fprintf(stderr, "Warning: nothing copied to clipboard\n");
+ return;
+ }
+
+ /* account for space/quote (3) and \0 (1) and & (1) */
+ /* e.g.: xdg-open "https://st.suckless.org"& */
+ size_t const cmd_size = max_cmd + strlen(clip) + 5;
+ char cmd[cmd_size];
+
+ snprintf(cmd, cmd_size, "%s \"%s\"&", (char *)arg->v, clip);
+ res = system(cmd);
+}
+\ No newline at end of file
diff --git a/patch/opencopied.h b/patch/opencopied.h
@@ -0,0 +1 @@
+void opencopied(const Arg *);
+\ No newline at end of file
diff --git a/patch/st_include.c b/patch/st_include.c
@@ -0,0 +1,9 @@
+/* Patches */
+
+#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+#include "copyurl.c"
+#endif
+
+#if NEWTERM_PATCH
+#include "newterm.c"
+#endif
+\ No newline at end of file
diff --git a/patch/st_include.h b/patch/st_include.h
@@ -0,0 +1,13 @@
+/* Patches */
+
+#if COPYURL_PATCH || COPYURL_HIGHLIGHT_SELECTED_URLS_PATCH
+#include "copyurl.h"
+#endif
+
+#if FIXIME_PATCH
+void xximspot(int, int);
+#endif
+
+#if NEWTERM_PATCH
+#include "newterm.h"
+#endif
+\ No newline at end of file
diff --git a/patch/x_include.c b/patch/x_include.c
@@ -0,0 +1,9 @@
+/* Patches */
+
+#if OPENCOPIED_PATCH
+#include "opencopied.c"
+#endif
+
+#if FIXIME_PATCH
+#include "fixime.c"
+#endif
+\ No newline at end of file
diff --git a/patch/x_include.h b/patch/x_include.h
@@ -0,0 +1,9 @@
+/* Patches */
+
+#if OPENCOPIED_PATCH
+#include "opencopied.h"
+#endif
+
+#if FIXIME_PATCH
+#include "fixime.h"
+#endif
+\ No newline at end of file
diff --git a/patches.h b/patches.h
@@ -46,14 +46,37 @@
/* This patch adds the option of disabling bold fonts globally.
* https://st.suckless.org/patches/disable_bold_italic_fonts/
*/
-#define DISABLE_BOLD_FONTS_PATCH 0
+#define DISABLE_BOLD_FONTS_PATCH 1
/* This patch adds the option of disabling italic fonts globally.
* https://st.suckless.org/patches/disable_bold_italic_fonts/
*/
-#define DISABLE_ITALIC_FONTS_PATCH 0
+#define DISABLE_ITALIC_FONTS_PATCH 1
/* This patch adds the option of disabling roman fonts globally.
* https://st.suckless.org/patches/disable_bold_italic_fonts/
*/
-#define DISABLE_ROMAN_FONTS_PATCH 0
+#define DISABLE_ROMAN_FONTS_PATCH 1
+
+/* This patch adds better Input Method Editor (IME) support.
+ * https://st.suckless.org/patches/fix_ime/
+ */
+#define FIXIME_PATCH 1
+
+/* Hide the X cursor whenever a key is pressed and show it back when the mouse is moved in
+ * the terminal window.
+ * https://st.suckless.org/patches/hidecursor/
+ */
+#define HIDECURSOR_PATCH 1
+
+/* This patch allows you to spawn a new st terminal using Ctrl-Shift-Return. It will have the
+ * same CWD (current working directory) as the original st instance.
+ * https://st.suckless.org/patches/newterm/
+ */
+#define NEWTERM_PATCH 1
+
+/* Open contents of the clipboard in a user-defined browser.
+ * https://st.suckless.org/patches/open_copied_url/
+ */
+#define OPENCOPIED_PATCH 1
+
diff --git a/st.c b/st.c
@@ -232,7 +232,7 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
-#include "patch/include.h"
+#include "patch/st_include.h"
ssize_t
xwrite(int fd, const char *s, size_t len)
@@ -2596,6 +2596,9 @@ draw(void)
term.ocx, term.ocy, term.line[term.ocy][term.ocx]);
term.ocx = cx, term.ocy = term.c.y;
xfinishdraw();
+ #if FIXIME_PATCH
+ xximspot(term.ocx, term.ocy);
+ #endif // FIXIME_PATCH
}
void
@@ -2605,4 +2608,4 @@ redraw(void)
draw();
}
-#include "patch/include.c"
-\ No newline at end of file
+#include "patch/st_include.c"
+\ No newline at end of file
diff --git a/x.c b/x.c
@@ -57,13 +57,12 @@ static void zoom(const Arg *);
static void zoomabs(const Arg *);
static void zoomreset(const Arg *);
-#include "patch/include.h"
+#include "patch/st_include.h"
+#include "patch/x_include.h"
/* config.h for applying patches and the configuration. */
#include "config.h"
-//#include "patch/include.c"
-
/* XEMBED messages */
#define XEMBED_FOCUS_IN 4
#define XEMBED_FOCUS_OUT 5
@@ -103,6 +102,13 @@ typedef struct {
Draw draw;
Visual *vis;
XSetWindowAttributes attrs;
+ #if HIDECURSOR_PATCH
+ /* Here, we use the term *pointer* to differentiate the cursor
+ * one sees when hovering the mouse over the terminal from, e.g.,
+ * a green rectangle where text would be entered. */
+ Cursor vpointer, bpointer; /* visible and hidden pointers */
+ int pointerisvisible;
+ #endif // HIDECURSOR_PATCH
int scr;
int isfixed; /* is fixed geometry? */
#if ALPHA_PATCH
@@ -253,6 +259,8 @@ static char *opt_title = NULL;
static int oldbutton = 3; /* button event on startup: 3 = release */
+#include "patch/x_include.c"
+
void
clipcopy(const Arg *dummy)
{
@@ -681,6 +689,15 @@ brelease(XEvent *e)
void
bmotion(XEvent *e)
{
+ #if HIDECURSOR_PATCH
+ if (!xw.pointerisvisible) {
+ XDefineCursor(xw.dpy, xw.win, xw.vpointer);
+ xw.pointerisvisible = 1;
+ if (!IS_SET(MODE_MOUSEMANY))
+ xsetpointermotion(0);
+ }
+ #endif // HIDECURSOR_PATCH
+
if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forceselmod)) {
mousereport(e);
return;
@@ -1058,7 +1075,11 @@ void
xinit(int cols, int rows)
{
XGCValues gcvalues;
+ #if HIDECURSOR_PATCH
+ Pixmap blankpm;
+ #else
Cursor cursor;
+ #endif // HIDECURSOR_PATCH
Window parent;
pid_t thispid = getpid();
XColor xmousefg, xmousebg;
@@ -1119,6 +1140,9 @@ xinit(int cols, int rows)
xw.attrs.border_pixel = dc.col[defaultbg].pixel;
xw.attrs.bit_gravity = NorthWestGravity;
xw.attrs.event_mask = FocusChangeMask | KeyPressMask
+ #if FIXIME_PATCH
+ | KeyReleaseMask
+ #endif // FIXIME_PATCH
| ExposureMask | VisibilityChangeMask | StructureNotifyMask
| ButtonMotionMask | ButtonPressMask | ButtonReleaseMask;
xw.attrs.colormap = xw.cmap;
@@ -1158,6 +1182,9 @@ xinit(int cols, int rows)
xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap);
/* input methods */
+ #if FIXIME_PATCH
+ ximopen(xw.dpy);
+ #else
if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=local");
if ((xw.xim = XOpenIM(xw.dpy, NULL, NULL, NULL)) == NULL) {
@@ -1174,10 +1201,17 @@ xinit(int cols, int rows)
XNFocusWindow, xw.win, NULL);
if (xw.xic == NULL)
die("XCreateIC failed. Could not obtain input method.\n");
+ #endif // FIXIME_PATCH
/* white cursor, black outline */
+ #if HIDECURSOR_PATCH
+ xw.pointerisvisible = 1;
+ xw.vpointer = XCreateFontCursor(xw.dpy, mouseshape);
+ XDefineCursor(xw.dpy, xw.win, xw.vpointer);
+ #else
cursor = XCreateFontCursor(xw.dpy, mouseshape);
XDefineCursor(xw.dpy, xw.win, cursor);
+ #endif // HIDECURSOR_PATCH
if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) {
xmousefg.red = 0xffff;
@@ -1191,7 +1225,14 @@ xinit(int cols, int rows)
xmousebg.blue = 0x0000;
}
+ #if HIDECURSOR_PATCH
+ XRecolorCursor(xw.dpy, xw.vpointer, &xmousefg, &xmousebg);
+ blankpm = XCreateBitmapFromData(xw.dpy, xw.win, &(char){0}, 1, 1);
+ xw.bpointer = XCreatePixmapCursor(xw.dpy, blankpm, blankpm,
+ &xmousefg, &xmousebg, 0, 0);
+ #else
XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg);
+ #endif // HIDECURSOR_PATCH
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False);
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False);
@@ -1733,6 +1774,10 @@ unmap(XEvent *ev)
void
xsetpointermotion(int set)
{
+ #if HIDECURSOR_PATCH
+ if (!set && !xw.pointerisvisible)
+ return;
+ #endif // HIDECURSOR_PATCH
MODBIT(xw.attrs.event_mask, set, PointerMotionMask);
XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs);
}
@@ -1851,6 +1896,14 @@ kpress(XEvent *ev)
Status status;
Shortcut *bp;
+ #if HIDECURSOR_PATCH
+ if (xw.pointerisvisible) {
+ XDefineCursor(xw.dpy, xw.win, xw.bpointer);
+ xsetpointermotion(1);
+ xw.pointerisvisible = 0;
+ }
+ #endif // HIDECURSOR_PATCH
+
if (IS_SET(MODE_KBDLOCK))
return;