rename some headers, because i plan on maybe doing wayland support

This commit is contained in:
speedie 2023-05-21 23:23:43 +02:00
parent 0e21c84508
commit 29781c8084
14 changed files with 179 additions and 185 deletions

View file

@ -314,8 +314,6 @@ its not like you will be unable to use spmenu in its current
state.</li> state.</li>
</ul></li> </ul></li>
</ul> </ul>
<h3 id="bugs">Bugs</h3>
<p>None discovered yet! :)</p>
<h2 id="scripts">Scripts</h2> <h2 id="scripts">Scripts</h2>
<p>Theres a page dedicated to user scripts <a <p>Theres a page dedicated to user scripts <a
href="https://spmenu.speedie.site/index.php/User+scripts">over on the href="https://spmenu.speedie.site/index.php/User+scripts">over on the

View file

@ -138,10 +138,6 @@ code which as of now seems unlikely, or if someone makes a patch.
- You can just use XWayland anyway if you happen to use Wayland, so it's not - You can just use XWayland anyway if you happen to use Wayland, so it's not
like you will be unable to use spmenu in its current state. like you will be unable to use spmenu in its current state.
### Bugs
None discovered yet! :)
## Scripts ## Scripts
There's a page dedicated to user scripts There's a page dedicated to user scripts

164
libs/x11/init.c Normal file
View file

@ -0,0 +1,164 @@
void setupdisplay(void) {
int x, y, i;
#if USEXINERAMA
int j, di;
#endif
unsigned int du;
unsigned int tmp, minstrlen = 0, curstrlen = 0;
int numwidthchecks = 100;
struct item *item;
XIM xim;
Window w, dw, *dws;
XWindowAttributes wa;
#if USEXINERAMA
XineramaScreenInfo *info;
Window pw;
int a, n, area = 0;
#endif
// set properties indicating what spmenu handles
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
types = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
// resize client
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
lines = MAX(lines, 0);
reallines = lines;
// resize client to image height if deemed necessary
#if USEIMAGE
if (image) resizetoimageheight(imageheight);
#endif
mh = (lines + 1) * bh + 2 * menumarginv; // lines + 1 * bh is the menu height
// set prompt width based on prompt size
promptw = (prompt && *prompt)
? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; // prompt width
// get accurate width
if (accuratewidth) {
for (item = items; !lines && item && item->text; ++item) {
curstrlen = strlen(item->text);
if (numwidthchecks || minstrlen < curstrlen) {
numwidthchecks = MAX(numwidthchecks - 1, 0);
minstrlen = MAX(minstrlen, curstrlen);
if ((tmp = MIN(TEXTW(item->text), mw/3) > inputw)) {
inputw = tmp;
if (tmp == mw/3)
break;
}
}
}
}
// init xinerama screens
#if USEXINERAMA
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
else if (w != root && w != PointerRoot && w != None) {
// find top-level window containing current input focus
do {
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
XFree(dws);
} while (w != root && w != pw);
// find xinerama screen with which the window intersects most
if (XGetWindowAttributes(dpy, pw, &wa))
for (j = 0; j < n; j++)
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
area = a;
i = j;
}
}
// no focused window is on screen, so use pointer location instead
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
for (i = 0; i < n; i++)
if (INTERSECT(x, y, 1, 1, info[i]))
break;
// calculate x/y position
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
} else { // top or bottom
x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos);
mw = (menuwidth>0 ? menuwidth : info[i].width);
}
XFree(info);
} else
#endif
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("spmenu: could not get embedding window attributes: 0x%lx",
parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else { // top or bottom
x = 0;
y = menuposition ? 0 : wa.width - mh - ypos;
mw = wa.width;
}
}
// might be faster in some instances, most of the time unnecessary
if (!accuratewidth) inputw = MIN(inputw, mw/3);
match(); // match entries
// create menu window and set properties for it
create_window(x + sp, y + vp - (menuposition == 1 ? 0 : menuposition == 2 ? borderwidth : borderwidth * 2), mw - 2 * sp - borderwidth * 2, mh);
set_window();
set_prop();
#if USEIMAGE
setimageopts();
#endif
// input methods
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=local");
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=");
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
die("XOpenIM failed: could not open input device");
}
}
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
XSync(dpy, False);
XGetWindowAttributes(dpy, win, &wa);
if (wa.map_state == IsViewable) // must be viewable, otherwise we get a BadMatch error
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
// embed spmenu inside parent window
if (embed) {
XReparentWindow(dpy, win, parentwin, x, y);
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
XSelectInput(dpy, dws[i], FocusChangeMask);
XFree(dws);
}
grabfocus();
}
// resize and draw
drw_resize(drw, mw - 2 * sp - borderwidth * 2, mh);
drawmenu();
}

1
libs/x11/init.h Normal file
View file

@ -0,0 +1 @@
static void setupdisplay(void);

193
spmenu.c
View file

@ -1,9 +1,9 @@
/* spmenu - fancy dynamic menu /* spmenu - fancy dynamic menu
* *
* If you're looking for functions used to draw text, see 'libs/draw.c' * If you're looking for functions used to draw text, see 'libs/draw.c'
* If you're looking for wrapper functions used inside the draw functions, see 'libs/sl/draw.c' * If you're looking for wrapper functions used inside the draw functions, see 'libs/libdrw/drw.c'
* If you're looking for functions used to draw images, see 'libs/img.c' * If you're looking for functions used to draw images, see 'libs/img.c'
* If you're looking for the .Xresources array, see 'libs/xresources.h' * If you're looking for the .Xresources array, see 'libs/x11/xresources.h'
* *
* You don't need to edit spmenu.c if you aren't making big changes to the software. * You don't need to edit spmenu.c if you aren't making big changes to the software.
* *
@ -118,13 +118,14 @@ static int allowkeys = 1; // whether or not to interpret a keypress as an insert
// various headers // various headers
#include "libs/libdrw/drw.h" #include "libs/libdrw/drw.h"
#include "libs/sl/main.h" #include "libs/sl/main.h"
#include "libs/x11/init.h"
#include "libs/draw.h" #include "libs/draw.h"
#include "libs/stream.h" #include "libs/stream.h"
#include "libs/schemes.h" #include "libs/schemes.h"
#include "libs/arg.h" #include "libs/arg.h"
#include "libs/xrdb.h" #include "libs/x11/xrdb.h"
#include "libs/key.h" #include "libs/x11/key.h"
#include "libs/mouse.h" #include "libs/x11/mouse.h"
#include "libs/sort.h" #include "libs/sort.h"
#include "libs/history.h" #include "libs/history.h"
@ -237,7 +238,6 @@ static void grabfocus(void);
static void pastesel(void); static void pastesel(void);
static void appenditem(struct item *item, struct item **list, struct item **last); static void appenditem(struct item *item, struct item **list, struct item **last);
static void xinitvisual(void); static void xinitvisual(void);
static void setupdisplay(void);
static int max_textw(void); static int max_textw(void);
static size_t nextrune(int inc); static size_t nextrune(int inc);
@ -252,7 +252,7 @@ static int listchanged = 0;
#include "mouse.h" #include "mouse.h"
// xresources/color arrays // xresources/color arrays
#include "libs/xresources.h" #include "libs/x11/xresources.h"
#include "libs/colors.h" #include "libs/colors.h"
static char *fonts[] = { font }; static char *fonts[] = { font };
@ -273,16 +273,16 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/img.c" #include "libs/img.c"
#include "libs/rtl.h" #include "libs/rtl.h"
#include "libs/rtl.c" #include "libs/rtl.c"
#include "libs/key.c" #include "libs/x11/key.c"
#include "libs/mouse.c" #include "libs/x11/mouse.c"
#include "libs/sort.c" #include "libs/sort.c"
#include "libs/draw.c" #include "libs/draw.c"
#include "libs/schemes.c" #include "libs/schemes.c"
#include "libs/argv.h" #include "libs/argv.h"
#include "libs/argv.c" #include "libs/argv.c"
#include "libs/xrdb.c" #include "libs/x11/xrdb.c"
#include "libs/client.h" #include "libs/x11/client.h"
#include "libs/client.c" #include "libs/x11/client.c"
#include "libs/match.h" #include "libs/match.h"
#include "libs/match.c" #include "libs/match.c"
#include "libs/history.c" #include "libs/history.c"
@ -290,6 +290,7 @@ static char *(*fstrstr)(const char *, const char *) = cistrstr;
#include "libs/stream.c" #include "libs/stream.c"
#include "libs/event.h" #include "libs/event.h"
#include "libs/event.c" #include "libs/event.c"
#include "libs/x11/init.c"
int is_selected(size_t index) { int is_selected(size_t index) {
for (int i = 0; i < sel_size; i++) { for (int i = 0; i < sel_size; i++) {
@ -554,173 +555,6 @@ void xinitvisual(void) {
} }
} }
void setupdisplay(void) {
int x, y, i;
#if USEXINERAMA
int j, di;
#endif
unsigned int du;
unsigned int tmp, minstrlen = 0, curstrlen = 0;
int numwidthchecks = 100;
struct item *item;
XIM xim;
Window w, dw, *dws;
XWindowAttributes wa;
#if USEXINERAMA
XineramaScreenInfo *info;
Window pw;
int a, n, area = 0;
#endif
init_appearance(); // init colorschemes by reading arrays
// set properties indicating what spmenu handles
clip = XInternAtom(dpy, "CLIPBOARD", False);
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
types = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
dock = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
// resize client
bh = MAX(drw->font->h, drw->font->h + 2 + lineheight);
lines = MAX(lines, 0);
reallines = lines;
// resize client to image height if deemed necessary
#if USEIMAGE
if (image) resizetoimageheight(imageheight);
#endif
mh = (lines + 1) * bh + 2 * menumarginv; // lines + 1 * bh is the menu height
// set prompt width based on prompt size
promptw = (prompt && *prompt)
? pango_prompt ? TEXTWM(prompt) : TEXTW(prompt) - lrpad / 4 : 0; // prompt width
// get accurate width
if (accuratewidth) {
for (item = items; !lines && item && item->text; ++item) {
curstrlen = strlen(item->text);
if (numwidthchecks || minstrlen < curstrlen) {
numwidthchecks = MAX(numwidthchecks - 1, 0);
minstrlen = MAX(minstrlen, curstrlen);
if ((tmp = MIN(TEXTW(item->text), mw/3) > inputw)) {
inputw = tmp;
if (tmp == mw/3)
break;
}
}
}
}
// init xinerama screens
#if USEXINERAMA
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
else if (w != root && w != PointerRoot && w != None) {
// find top-level window containing current input focus
do {
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
XFree(dws);
} while (w != root && w != pw);
// find xinerama screen with which the window intersects most
if (XGetWindowAttributes(dpy, pw, &wa))
for (j = 0; j < n; j++)
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
area = a;
i = j;
}
}
// no focused window is on screen, so use pointer location instead
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
for (i = 0; i < n; i++)
if (INTERSECT(x, y, 1, 1, info[i]))
break;
// calculate x/y position
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
} else { // top or bottom
x = info[i].x_org + xpos;
y = info[i].y_org + (menuposition ? 0 : info[i].height - mh - ypos);
mw = (menuwidth>0 ? menuwidth : info[i].width);
}
XFree(info);
} else
#endif
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("spmenu: could not get embedding window attributes: 0x%lx",
parentwin); // die because unable to get attributes for the parent window
if (menuposition == 2) { // centered
mw = MIN(MAX(max_textw() + promptw, minwidth), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else { // top or bottom
x = 0;
y = menuposition ? 0 : wa.width - mh - ypos;
mw = wa.width;
}
}
// might be faster in some instances, most of the time unnecessary
if (!accuratewidth) inputw = MIN(inputw, mw/3);
match(); // match entries
// create menu window and set properties for it
create_window(x + sp, y + vp - (menuposition == 1 ? 0 : menuposition == 2 ? borderwidth : borderwidth * 2), mw - 2 * sp - borderwidth * 2, mh);
set_window();
set_prop();
#if USEIMAGE
setimageopts();
#endif
// input methods
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=local");
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL) {
XSetLocaleModifiers("@im=");
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
die("XOpenIM failed: could not open input device");
}
}
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
XSync(dpy, False);
XGetWindowAttributes(dpy, win, &wa);
if (wa.map_state == IsViewable) // must be viewable, otherwise we get a BadMatch error
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
// embed spmenu inside parent window
if (embed) {
XReparentWindow(dpy, win, parentwin, x, y);
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
XSelectInput(dpy, dws[i], FocusChangeMask);
XFree(dws);
}
grabfocus();
}
// resize and draw
drw_resize(drw, mw - 2 * sp - borderwidth * 2, mh);
drawmenu();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
XWindowAttributes wa; XWindowAttributes wa;
@ -804,6 +638,7 @@ int main(int argc, char *argv[]) {
} }
#endif #endif
init_appearance(); // init colorschemes by reading arrays
setupdisplay(); // set up display and create window setupdisplay(); // set up display and create window
eventloop(); // function is a loop which checks X11 events and calls other functions accordingly eventloop(); // function is a loop which checks X11 events and calls other functions accordingly