Add Contacts DWM plugin, desktop Menu/Names softkey labels, and 15px plugin label fonts
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -154,10 +154,10 @@ fast_sys_choices() {
|
||||
$icon_grd Apps^0^sxmo_appmenu.sh applications
|
||||
$icon_grd Scripts^0^sxmo_appmenu.sh scripts
|
||||
$icon_dir Files^0^sxmo_files.sh
|
||||
$icon_phn Dialer^0^sxmo_modemdial.sh
|
||||
$icon_phn Dialer^0^xdialer
|
||||
$icon_phl Call Log^0^xcalllog
|
||||
$icon_msg Texts^0^sxmo_modemtext.sh
|
||||
$icon_usr Contacts^0^sxmo_contactmenu.sh
|
||||
$icon_usr Contacts^0^xcontacts
|
||||
${_bt_line}$icon_cam Camera^0^bananarchy-photo --menu
|
||||
${_flash_line}$icon_net Networks^0^sxmo_networks.sh
|
||||
$icon_mus Audio^0^sxmo_audio.sh
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
if command -v xcontacts >/dev/null 2>&1; then
|
||||
exec xcontacts "$@"
|
||||
fi
|
||||
exec /usr/bin/dwm-plugin contacts "$@"
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
dwm-plugin
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -767,9 +767,10 @@ case "$WMCLASS" in
|
||||
$icon_grd Apps ^ 0 ^ sxmo_appmenu.sh applications
|
||||
$icon_grd Scripts ^ 0 ^ sxmo_appmenu.sh scripts
|
||||
$icon_dir Files ^ 0 ^ sxmo_files.sh
|
||||
$icon_phn Dialer ^ 0 ^ sxmo_modemdial.sh
|
||||
$icon_phn Dialer ^ 0 ^ xdialer
|
||||
$icon_phl Call Log ^ 0 ^ xcalllog
|
||||
$icon_msg Texts ^ 0 ^ sxmo_modemtext.sh
|
||||
$icon_usr Contacts ^ 0 ^ sxmo_contactmenu.sh
|
||||
$icon_usr Contacts ^ 0 ^ xcontacts
|
||||
$(
|
||||
bt_is_unblocked &&
|
||||
printf %b "$icon_bth Bluetooth ^ 1 ^ sxmo_bluetoothmenu.sh"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
dwm-plugin
|
||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -97,7 +97,7 @@ EOF
|
||||
dwm.c drw.c util.c $DWM_LIBS -o /bananarchy/prebuilt/sxmo-x11/usr/bin/dwm
|
||||
$STRIP --strip-unneeded /bananarchy/prebuilt/sxmo-x11/usr/bin/dwm
|
||||
|
||||
echo "[6/6] Compiling DWM Plugins (xdrawer.so, dialer.so, calllog.so) and dwm-plugin runner..."
|
||||
echo "[6/6] Compiling DWM Plugins (xdrawer.so, dialer.so, calllog.so, contacts.so) and dwm-plugin runner..."
|
||||
mkdir -p /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins
|
||||
PLUG_INCS="$(pkgconf --cflags x11 xft fontconfig freetype2 pango pangoxft alsa)"
|
||||
PLUG_LIBS="$(pkgconf --libs x11 xft fontconfig freetype2 pango pangoxft alsa)"
|
||||
@@ -114,10 +114,15 @@ EOF
|
||||
/bananarchy/src/dwm-plugins/calllog_plugin.cpp $PLUG_LIBS \
|
||||
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so
|
||||
|
||||
$CXX $OPT_CFLAGS -fPIC -shared -std=c++17 -Wall -Wextra $PLUG_INCS \
|
||||
/bananarchy/src/dwm-plugins/contacts_plugin.cpp $PLUG_LIBS \
|
||||
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so
|
||||
|
||||
$STRIP --strip-unneeded \
|
||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so \
|
||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/dialer.so \
|
||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so
|
||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so \
|
||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/contacts.so
|
||||
|
||||
$CC $OPT_CFLAGS -std=c99 -D_DEFAULT_SOURCE -Wall -Wextra \
|
||||
/bananarchy/src/dwm-plugins/dwm_plugin_runner.c -ldl \
|
||||
@@ -128,6 +133,7 @@ EOF
|
||||
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/XDrawer
|
||||
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xdialer
|
||||
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xcalllog
|
||||
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xcontacts
|
||||
|
||||
mkdir -p /bananarchy/overlay/rootfs/usr/bin /bananarchy/overlay/rootfs/usr/lib/dwm/plugins
|
||||
cp -a /bananarchy/prebuilt/sxmo-x11/usr/bin/. /bananarchy/overlay/rootfs/usr/bin/
|
||||
|
||||
@@ -102,17 +102,17 @@ int calllog_run_main(int argc, char** argv) {
|
||||
|
||||
PangoLayout* layoutMain = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descMain =
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 14px");
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 15px");
|
||||
pango_layout_set_font_description(layoutMain, descMain);
|
||||
|
||||
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descSmall =
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 11px");
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 12px");
|
||||
pango_layout_set_font_description(layoutSmall, descSmall);
|
||||
|
||||
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descIcon =
|
||||
pango_font_description_from_string("DejaVuSansM Nerd Font, Fira Code 15px");
|
||||
pango_font_description_from_string("DejaVuSansM Nerd Font, Fira Code 16px");
|
||||
pango_layout_set_font_description(layoutIcon, descIcon);
|
||||
|
||||
auto allocColor = [&](const char* hex) {
|
||||
@@ -324,14 +324,14 @@ int calllog_run_main(int argc, char** argv) {
|
||||
XSetForeground(dpy, gc, 0x444444);
|
||||
XFillRectangle(dpy, pix, gc, 0, sbY, kWinWidth, 1);
|
||||
|
||||
drawPango(layoutSmall, &colLight, 6, sbY + 1, kSoftbarH - 1, "Dialer");
|
||||
drawPango(layoutMain, &colLight, 6, sbY + 1, kSoftbarH - 1, "Dialer");
|
||||
std::string centerLabel = "CALL";
|
||||
int cw = pangoWidth(layoutMain, centerLabel);
|
||||
drawPango(layoutMain, filtered.empty() ? &colMuted : &colGreen,
|
||||
(kWinWidth - cw) / 2, sbY + 1, kSoftbarH - 1, centerLabel);
|
||||
std::string rightLabel = "Close";
|
||||
int rw = pangoWidth(layoutSmall, rightLabel);
|
||||
drawPango(layoutSmall, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||
int rw = pangoWidth(layoutMain, rightLabel);
|
||||
drawPango(layoutMain, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||
kSoftbarH - 1, rightLabel);
|
||||
|
||||
if (visible) {
|
||||
@@ -350,6 +350,9 @@ int calllog_run_main(int argc, char** argv) {
|
||||
if (isPidFileAlive(getRuntimeFile("xdialer.pid"))) {
|
||||
sendPluginCommand("dialer", "CLOSE");
|
||||
}
|
||||
if (isPidFileAlive(getRuntimeFile("xcontacts.pid"))) {
|
||||
sendPluginCommand("contacts", "CLOSE");
|
||||
}
|
||||
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
||||
sendPluginCommand("xdrawer", "CLOSE");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -112,17 +112,17 @@ int dialer_run_main(int argc, char** argv) {
|
||||
|
||||
PangoLayout* layoutMain = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descMain =
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 14px");
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 15px");
|
||||
pango_layout_set_font_description(layoutMain, descMain);
|
||||
|
||||
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descSmall =
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 11px");
|
||||
pango_font_description_from_string("Fira Code, DejaVuSansM Nerd Font 12px");
|
||||
pango_layout_set_font_description(layoutSmall, descSmall);
|
||||
|
||||
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
||||
PangoFontDescription* descIcon =
|
||||
pango_font_description_from_string("DejaVuSansM Nerd Font, Fira Code 15px");
|
||||
pango_font_description_from_string("DejaVuSansM Nerd Font, Fira Code 16px");
|
||||
pango_layout_set_font_description(layoutIcon, descIcon);
|
||||
|
||||
auto allocColor = [&](const char* hex) {
|
||||
@@ -360,12 +360,12 @@ int dialer_run_main(int argc, char** argv) {
|
||||
std::string centerLabel = "CALL";
|
||||
std::string rightLabel = number.empty() ? "Close" : "Clear";
|
||||
|
||||
drawPango(layoutSmall, &colLight, 6, sbY + 1, kSoftbarH - 1, leftLabel);
|
||||
drawPango(layoutMain, &colLight, 6, sbY + 1, kSoftbarH - 1, leftLabel);
|
||||
int cw = pangoWidth(layoutMain, centerLabel);
|
||||
drawPango(layoutMain, &colGreen, (kWinWidth - cw) / 2, sbY + 1,
|
||||
kSoftbarH - 1, centerLabel);
|
||||
int rw = pangoWidth(layoutSmall, rightLabel);
|
||||
drawPango(layoutSmall, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||
int rw = pangoWidth(layoutMain, rightLabel);
|
||||
drawPango(layoutMain, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||
kSoftbarH - 1, rightLabel);
|
||||
|
||||
if (visible) {
|
||||
@@ -389,6 +389,9 @@ int dialer_run_main(int argc, char** argv) {
|
||||
if (isPidFileAlive(getRuntimeFile("xcalllog.pid"))) {
|
||||
sendPluginCommand("calllog", "CLOSE");
|
||||
}
|
||||
if (isPidFileAlive(getRuntimeFile("xcontacts.pid"))) {
|
||||
sendPluginCommand("contacts", "CLOSE");
|
||||
}
|
||||
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
||||
sendPluginCommand("xdrawer", "CLOSE");
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ static int try_send_plugin_fifo(const char *plugin_name, int sub_argc, char **su
|
||||
int len = 0;
|
||||
if (strcmp(plugin_name, "xdrawer") == 0) {
|
||||
len = snprintf(cmd, sizeof(cmd), "TOGGLE\n");
|
||||
} else if (sub_argc >= 2 && sub_argv[1] && strcmp(sub_argv[1], "newcontact") == 0) {
|
||||
const char *num = (sub_argc >= 3 && sub_argv[2]) ? sub_argv[2] : "";
|
||||
len = snprintf(cmd, sizeof(cmd), "OPEN new:%s\n", num);
|
||||
} else if (sub_argc >= 2 && sub_argv[1] && sub_argv[1][0]) {
|
||||
len = snprintf(cmd, sizeof(cmd), "OPEN %s\n", sub_argv[1]);
|
||||
} else {
|
||||
@@ -67,6 +70,9 @@ static const char *resolve_plugin_name_from_argv0(const char *argv0) {
|
||||
if (strcasecmp(base, "xcalllog") == 0 || strcasecmp(base, "calllog") == 0) {
|
||||
return "calllog";
|
||||
}
|
||||
if (strcasecmp(base, "xcontacts") == 0 || strcasecmp(base, "contacts") == 0) {
|
||||
return "contacts";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,11 +40,19 @@ constexpr int kWinHeight = kScreenHeight - kTopBarHeight; // 296px flush below 2
|
||||
constexpr const char* kIconPhone = "\xef\x82\x95"; // U+F095 phone handset
|
||||
constexpr const char* kIconPhoneLog = "\xef\x82\x98"; // U+F098 phone square
|
||||
constexpr const char* kIconUser = "\xef\x80\x87"; // U+F007 user contact
|
||||
constexpr const char* kIconBook = "\xef\x83\x80"; // U+F0C0 address book / users
|
||||
constexpr const char* kIconClock = "\xef\x80\x97"; // U+F017 recent clock
|
||||
constexpr const char* kIconOutCall = "\xef\x85\xb8"; // U+F178 outgoing arrow
|
||||
constexpr const char* kIconInCall = "\xef\x85\xb5"; // U+F175 incoming arrow
|
||||
constexpr const char* kIconMissedCall = "\xef\x81\xb1"; // U+F071 missed/alert
|
||||
constexpr const char* kIconBackspace = "\xef\x86\x90"; // U+F190 left circle arrow
|
||||
constexpr const char* kIconSearch = "\xef\x80\x82"; // U+F002 search
|
||||
constexpr const char* kIconPlus = "\xef\x81\xa7"; // U+F067 plus/add
|
||||
constexpr const char* kIconEdit = "\xef\x81\x84"; // U+F044 edit
|
||||
constexpr const char* kIconTrash = "\xef\x87\xb8"; // U+F1F8 delete/trash
|
||||
constexpr const char* kIconSms = "\xef\x83\xa0"; // U+F0E0 envelope/SMS
|
||||
constexpr const char* kIconList = "\xef\x80\xba"; // U+F03A list
|
||||
constexpr const char* kIconCheck = "\xef\x80\x8c"; // U+F00C check
|
||||
|
||||
inline int64_t nowMs() {
|
||||
struct timespec ts {};
|
||||
@@ -525,6 +533,176 @@ class ContactBook {
|
||||
return out;
|
||||
}
|
||||
|
||||
const std::vector<ContactEntry>& savedContacts() const { return saved_; }
|
||||
|
||||
std::vector<std::string> unknownRecentNumbers() const {
|
||||
std::vector<std::string> out;
|
||||
std::unordered_set<std::string> seen;
|
||||
std::ifstream lf(getModemLogFilePath());
|
||||
std::vector<std::string> logLines;
|
||||
std::string line;
|
||||
while (std::getline(lf, line)) {
|
||||
if (!line.empty()) {
|
||||
logLines.push_back(line);
|
||||
}
|
||||
}
|
||||
for (auto it = logLines.rbegin(); it != logLines.rend(); ++it) {
|
||||
size_t t1 = it->find('\t');
|
||||
if (t1 == std::string::npos) continue;
|
||||
size_t t2 = it->find('\t', t1 + 1);
|
||||
if (t2 == std::string::npos) continue;
|
||||
size_t t3 = it->find('\t', t2 + 1);
|
||||
std::string num = trimStr(
|
||||
t3 == std::string::npos ? it->substr(t2 + 1)
|
||||
: it->substr(t2 + 1, t3 - t2 - 1));
|
||||
if (num.empty() || num == "NULL" || num.find('+', 1) != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
std::string norm = normalizePhone(num);
|
||||
if (norm.empty() || !resolveName(num).empty()) {
|
||||
continue;
|
||||
}
|
||||
std::string key = phoneSuffixKey(norm);
|
||||
if (seen.count(key) || seen.count(norm)) {
|
||||
continue;
|
||||
}
|
||||
seen.insert(key);
|
||||
seen.insert(norm);
|
||||
out.push_back(num);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void ensureParentDir(const std::string& filePath) {
|
||||
size_t slash = filePath.rfind('/');
|
||||
if (slash == std::string::npos || slash == 0) {
|
||||
return;
|
||||
}
|
||||
std::string dir = filePath.substr(0, slash);
|
||||
std::string cur;
|
||||
for (size_t i = 0; i < dir.size(); ++i) {
|
||||
cur.push_back(dir[i]);
|
||||
if (dir[i] == '/' && cur.size() > 1) {
|
||||
::mkdir(cur.c_str(), 0755);
|
||||
}
|
||||
}
|
||||
::mkdir(dir.c_str(), 0755);
|
||||
}
|
||||
|
||||
bool addOrUpdateContact(const std::string& oldNumber,
|
||||
const std::string& oldName,
|
||||
const std::string& newNumberRaw,
|
||||
const std::string& newNameRaw) {
|
||||
std::string newNumber = trimStr(newNumberRaw);
|
||||
std::string newName = trimStr(newNameRaw);
|
||||
for (char& ch : newName) {
|
||||
if (ch == '\t' || ch == '\r' || ch == '\n') {
|
||||
ch = ' ';
|
||||
}
|
||||
}
|
||||
if (newNumber.empty() || newName.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::string path = getContactsFilePath();
|
||||
ensureParentDir(path);
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> rows;
|
||||
{
|
||||
std::ifstream in(path);
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
if (line.empty()) continue;
|
||||
size_t tab = line.find('\t');
|
||||
if (tab == std::string::npos) continue;
|
||||
std::string num = trimStr(line.substr(0, tab));
|
||||
std::string name = trimStr(line.substr(tab + 1));
|
||||
if (!num.empty() && !name.empty()) {
|
||||
rows.push_back({num, name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool replaced = false;
|
||||
std::string oldNorm = normalizePhone(oldNumber);
|
||||
std::string newNorm = normalizePhone(newNumber);
|
||||
for (auto& r : rows) {
|
||||
if (!oldNumber.empty() &&
|
||||
((r.first == oldNumber && r.second == oldName) ||
|
||||
(!oldNorm.empty() && normalizePhone(r.first) == oldNorm &&
|
||||
r.second == oldName))) {
|
||||
r.first = newNumber;
|
||||
r.second = newName;
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!replaced && oldNumber.empty()) {
|
||||
for (auto& r : rows) {
|
||||
if (r.first == newNumber ||
|
||||
(!newNorm.empty() && normalizePhone(r.first) == newNorm)) {
|
||||
r.first = newNumber;
|
||||
r.second = newName;
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!replaced) {
|
||||
rows.push_back({newNumber, newName});
|
||||
}
|
||||
|
||||
std::ofstream out(path, std::ios::trunc);
|
||||
if (!out.is_open()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& r : rows) {
|
||||
out << r.first << "\t" << r.second << "\n";
|
||||
}
|
||||
out.close();
|
||||
load();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deleteContact(const std::string& number, const std::string& name) {
|
||||
std::string path = getContactsFilePath();
|
||||
std::vector<std::pair<std::string, std::string>> rows;
|
||||
std::string targetNorm = normalizePhone(number);
|
||||
bool removed = false;
|
||||
{
|
||||
std::ifstream in(path);
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
if (line.empty()) continue;
|
||||
size_t tab = line.find('\t');
|
||||
if (tab == std::string::npos) continue;
|
||||
std::string num = trimStr(line.substr(0, tab));
|
||||
std::string nm = trimStr(line.substr(tab + 1));
|
||||
if (num.empty() || nm.empty()) continue;
|
||||
if (!removed &&
|
||||
((num == number && nm == name) ||
|
||||
(!targetNorm.empty() && normalizePhone(num) == targetNorm &&
|
||||
nm == name))) {
|
||||
removed = true;
|
||||
continue;
|
||||
}
|
||||
rows.push_back({num, nm});
|
||||
}
|
||||
}
|
||||
if (!removed) {
|
||||
return false;
|
||||
}
|
||||
std::ofstream out(path, std::ios::trunc);
|
||||
if (!out.is_open()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& r : rows) {
|
||||
out << r.first << "\t" << r.second << "\n";
|
||||
}
|
||||
out.close();
|
||||
load();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ContactEntry> saved_;
|
||||
std::unordered_map<std::string, std::string> exactMap_;
|
||||
|
||||
+61
-4
@@ -49,6 +49,7 @@
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xcb/res.h>
|
||||
#include <pango/pango.h>
|
||||
#include <pango/pangoxft.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
@@ -147,6 +148,7 @@ struct Monitor {
|
||||
Client *stack;
|
||||
Monitor *next;
|
||||
Window barwin;
|
||||
Window softwin;
|
||||
const Layout *lt[2];
|
||||
};
|
||||
|
||||
@@ -769,6 +771,10 @@ cleanupmon(Monitor *mon)
|
||||
}
|
||||
XUnmapWindow(dpy, mon->barwin);
|
||||
XDestroyWindow(dpy, mon->barwin);
|
||||
if (mon->softwin) {
|
||||
XUnmapWindow(dpy, mon->softwin);
|
||||
XDestroyWindow(dpy, mon->softwin);
|
||||
}
|
||||
free(mon);
|
||||
}
|
||||
|
||||
@@ -1021,6 +1027,35 @@ drawbar(Monitor *m)
|
||||
drw_text(drw, MAX(x, m->ww - sw), 0, sw, bh, 0, s, 0, True);
|
||||
}
|
||||
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
|
||||
if (m->softwin && drw && drw->font) {
|
||||
XLowerWindow(dpy, m->softwin);
|
||||
XClearWindow(dpy, m->softwin);
|
||||
if (!m->sel) {
|
||||
XftDraw *d = XftDrawCreate(dpy, m->softwin,
|
||||
DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));
|
||||
if (d) {
|
||||
unsigned int ew = 0, eh = 0;
|
||||
const char *left_txt = "Menu";
|
||||
const char *right_txt = "Names";
|
||||
int sh_bar = 26;
|
||||
|
||||
drw_font_getexts(drw->font, left_txt, strlen(left_txt), &ew, &eh, False);
|
||||
int ty = (sh_bar - (int)eh) / 2;
|
||||
pango_layout_set_text(drw->font->layout, left_txt, strlen(left_txt));
|
||||
pango_xft_render_layout(d, &scheme[SchemeSel][ColFg],
|
||||
drw->font->layout, 6 * PANGO_SCALE, ty * PANGO_SCALE);
|
||||
|
||||
drw_font_getexts(drw->font, right_txt, strlen(right_txt), &ew, &eh, False);
|
||||
ty = (sh_bar - (int)eh) / 2;
|
||||
int rx = m->ww - (int)ew - 6;
|
||||
pango_layout_set_text(drw->font->layout, right_txt, strlen(right_txt));
|
||||
pango_xft_render_layout(d, &scheme[SchemeSel][ColFg],
|
||||
drw->font->layout, rx * PANGO_SCALE, ty * PANGO_SCALE);
|
||||
|
||||
XftDrawDestroy(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1806,6 +1841,10 @@ flush_pending_softkey(void)
|
||||
const Arg syscmd = { .v = (const char*[]){ "sxmo_appmenu.sh", "sys", NULL } };
|
||||
last_menu_pgid = spawn_pgid(&syscmd);
|
||||
} else if (pending == SOFTKEY_RIGHT) {
|
||||
if (host_is_idle_desktop() &&
|
||||
dispatch_plugin_idle_key(XF86XK_Back, 166, 0)) {
|
||||
return;
|
||||
}
|
||||
const Arg ctxcmd = { .v = (const char*[]){ "sxmo_appmenu.sh", NULL } };
|
||||
last_menu_pgid = spawn_pgid(&ctxcmd);
|
||||
}
|
||||
@@ -2170,9 +2209,12 @@ propertynotify(XEvent *e)
|
||||
Window trans;
|
||||
XPropertyEvent *ev = &e->xproperty;
|
||||
|
||||
if ((ev->window == root) && (ev->atom == XA_WM_NAME))
|
||||
updatestatus();
|
||||
else if (ev->state == PropertyDelete)
|
||||
if (ev->window == root) {
|
||||
if (ev->atom == XA_WM_NAME)
|
||||
updatestatus();
|
||||
else
|
||||
drawbars();
|
||||
} else if (ev->state == PropertyDelete)
|
||||
return; /* ignore */
|
||||
else if ((c = wintoclient(ev->window))) {
|
||||
switch(ev->atom) {
|
||||
@@ -2902,6 +2944,21 @@ updatebars(void)
|
||||
};
|
||||
XClassHint ch = {"dwm", "dwm"};
|
||||
for (m = mons; m; m = m->next) {
|
||||
if (!m->softwin) {
|
||||
XSetWindowAttributes softwa = {
|
||||
.override_redirect = True,
|
||||
.background_pixmap = ParentRelative,
|
||||
.event_mask = ExposureMask
|
||||
};
|
||||
int sh_bar = 26;
|
||||
m->softwin = XCreateWindow(dpy, root, m->wx, m->my + m->mh - sh_bar, m->ww, sh_bar, 0,
|
||||
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
|
||||
CWOverrideRedirect|CWBackPixmap|CWEventMask, &softwa);
|
||||
XDefineCursor(dpy, m->softwin, cursor[CurNormal]->cursor);
|
||||
XMapWindow(dpy, m->softwin);
|
||||
XLowerWindow(dpy, m->softwin);
|
||||
XSetClassHint(dpy, m->softwin, &ch);
|
||||
}
|
||||
if (m->barwin)
|
||||
continue;
|
||||
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
||||
@@ -3266,7 +3323,7 @@ wintomon(Window w)
|
||||
if (w == root && getrootptr(&x, &y))
|
||||
return recttomon(x, y, 1, 1);
|
||||
for (m = mons; m; m = m->next)
|
||||
if (w == m->barwin)
|
||||
if (w == m->barwin || w == m->softwin)
|
||||
return m;
|
||||
if ((c = wintoclient(w)))
|
||||
return c->mon;
|
||||
|
||||
@@ -703,6 +703,7 @@ static int xdrawer_run_main(int argc, char** argv) {
|
||||
}
|
||||
closeOtherPlugin("xdialer.pid", "/tmp/dwm_plugin_dialer.fifo");
|
||||
closeOtherPlugin("xcalllog.pid", "/tmp/dwm_plugin_calllog.fifo");
|
||||
closeOtherPlugin("xcontacts.pid", "/tmp/dwm_plugin_contacts.fifo");
|
||||
openStartMs = nowMs();
|
||||
startupIgnoreUntilMs = openStartMs + 180;
|
||||
initialKeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||
|
||||
Reference in New Issue
Block a user