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 Apps^0^sxmo_appmenu.sh applications
|
||||||
$icon_grd Scripts^0^sxmo_appmenu.sh scripts
|
$icon_grd Scripts^0^sxmo_appmenu.sh scripts
|
||||||
$icon_dir Files^0^sxmo_files.sh
|
$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_phl Call Log^0^xcalllog
|
||||||
$icon_msg Texts^0^sxmo_modemtext.sh
|
$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
|
${_bt_line}$icon_cam Camera^0^bananarchy-photo --menu
|
||||||
${_flash_line}$icon_net Networks^0^sxmo_networks.sh
|
${_flash_line}$icon_net Networks^0^sxmo_networks.sh
|
||||||
$icon_mus Audio^0^sxmo_audio.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 Apps ^ 0 ^ sxmo_appmenu.sh applications
|
||||||
$icon_grd Scripts ^ 0 ^ sxmo_appmenu.sh scripts
|
$icon_grd Scripts ^ 0 ^ sxmo_appmenu.sh scripts
|
||||||
$icon_dir Files ^ 0 ^ sxmo_files.sh
|
$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_msg Texts ^ 0 ^ sxmo_modemtext.sh
|
||||||
$icon_usr Contacts ^ 0 ^ sxmo_contactmenu.sh
|
$icon_usr Contacts ^ 0 ^ xcontacts
|
||||||
$(
|
$(
|
||||||
bt_is_unblocked &&
|
bt_is_unblocked &&
|
||||||
printf %b "$icon_bth Bluetooth ^ 1 ^ sxmo_bluetoothmenu.sh"
|
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
|
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
|
$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
|
mkdir -p /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins
|
||||||
PLUG_INCS="$(pkgconf --cflags x11 xft fontconfig freetype2 pango pangoxft alsa)"
|
PLUG_INCS="$(pkgconf --cflags x11 xft fontconfig freetype2 pango pangoxft alsa)"
|
||||||
PLUG_LIBS="$(pkgconf --libs 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 \
|
/bananarchy/src/dwm-plugins/calllog_plugin.cpp $PLUG_LIBS \
|
||||||
-o /bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/calllog.so
|
-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 \
|
$STRIP --strip-unneeded \
|
||||||
/bananarchy/prebuilt/sxmo-x11/usr/lib/dwm/plugins/xdrawer.so \
|
/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/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 \
|
$CC $OPT_CFLAGS -std=c99 -D_DEFAULT_SOURCE -Wall -Wextra \
|
||||||
/bananarchy/src/dwm-plugins/dwm_plugin_runner.c -ldl \
|
/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/XDrawer
|
||||||
ln -sf dwm-plugin /bananarchy/prebuilt/sxmo-x11/usr/bin/xdialer
|
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/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
|
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/
|
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);
|
PangoLayout* layoutMain = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descMain =
|
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);
|
pango_layout_set_font_description(layoutMain, descMain);
|
||||||
|
|
||||||
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descSmall =
|
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);
|
pango_layout_set_font_description(layoutSmall, descSmall);
|
||||||
|
|
||||||
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descIcon =
|
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);
|
pango_layout_set_font_description(layoutIcon, descIcon);
|
||||||
|
|
||||||
auto allocColor = [&](const char* hex) {
|
auto allocColor = [&](const char* hex) {
|
||||||
@@ -324,14 +324,14 @@ int calllog_run_main(int argc, char** argv) {
|
|||||||
XSetForeground(dpy, gc, 0x444444);
|
XSetForeground(dpy, gc, 0x444444);
|
||||||
XFillRectangle(dpy, pix, gc, 0, sbY, kWinWidth, 1);
|
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";
|
std::string centerLabel = "CALL";
|
||||||
int cw = pangoWidth(layoutMain, centerLabel);
|
int cw = pangoWidth(layoutMain, centerLabel);
|
||||||
drawPango(layoutMain, filtered.empty() ? &colMuted : &colGreen,
|
drawPango(layoutMain, filtered.empty() ? &colMuted : &colGreen,
|
||||||
(kWinWidth - cw) / 2, sbY + 1, kSoftbarH - 1, centerLabel);
|
(kWinWidth - cw) / 2, sbY + 1, kSoftbarH - 1, centerLabel);
|
||||||
std::string rightLabel = "Close";
|
std::string rightLabel = "Close";
|
||||||
int rw = pangoWidth(layoutSmall, rightLabel);
|
int rw = pangoWidth(layoutMain, rightLabel);
|
||||||
drawPango(layoutSmall, &colLight, kWinWidth - rw - 6, sbY + 1,
|
drawPango(layoutMain, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||||
kSoftbarH - 1, rightLabel);
|
kSoftbarH - 1, rightLabel);
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@@ -350,6 +350,9 @@ int calllog_run_main(int argc, char** argv) {
|
|||||||
if (isPidFileAlive(getRuntimeFile("xdialer.pid"))) {
|
if (isPidFileAlive(getRuntimeFile("xdialer.pid"))) {
|
||||||
sendPluginCommand("dialer", "CLOSE");
|
sendPluginCommand("dialer", "CLOSE");
|
||||||
}
|
}
|
||||||
|
if (isPidFileAlive(getRuntimeFile("xcontacts.pid"))) {
|
||||||
|
sendPluginCommand("contacts", "CLOSE");
|
||||||
|
}
|
||||||
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
||||||
sendPluginCommand("xdrawer", "CLOSE");
|
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);
|
PangoLayout* layoutMain = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descMain =
|
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);
|
pango_layout_set_font_description(layoutMain, descMain);
|
||||||
|
|
||||||
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
PangoLayout* layoutSmall = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descSmall =
|
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);
|
pango_layout_set_font_description(layoutSmall, descSmall);
|
||||||
|
|
||||||
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
PangoLayout* layoutIcon = pango_layout_new(pangoCtx);
|
||||||
PangoFontDescription* descIcon =
|
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);
|
pango_layout_set_font_description(layoutIcon, descIcon);
|
||||||
|
|
||||||
auto allocColor = [&](const char* hex) {
|
auto allocColor = [&](const char* hex) {
|
||||||
@@ -360,12 +360,12 @@ int dialer_run_main(int argc, char** argv) {
|
|||||||
std::string centerLabel = "CALL";
|
std::string centerLabel = "CALL";
|
||||||
std::string rightLabel = number.empty() ? "Close" : "Clear";
|
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);
|
int cw = pangoWidth(layoutMain, centerLabel);
|
||||||
drawPango(layoutMain, &colGreen, (kWinWidth - cw) / 2, sbY + 1,
|
drawPango(layoutMain, &colGreen, (kWinWidth - cw) / 2, sbY + 1,
|
||||||
kSoftbarH - 1, centerLabel);
|
kSoftbarH - 1, centerLabel);
|
||||||
int rw = pangoWidth(layoutSmall, rightLabel);
|
int rw = pangoWidth(layoutMain, rightLabel);
|
||||||
drawPango(layoutSmall, &colLight, kWinWidth - rw - 6, sbY + 1,
|
drawPango(layoutMain, &colLight, kWinWidth - rw - 6, sbY + 1,
|
||||||
kSoftbarH - 1, rightLabel);
|
kSoftbarH - 1, rightLabel);
|
||||||
|
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@@ -389,6 +389,9 @@ int dialer_run_main(int argc, char** argv) {
|
|||||||
if (isPidFileAlive(getRuntimeFile("xcalllog.pid"))) {
|
if (isPidFileAlive(getRuntimeFile("xcalllog.pid"))) {
|
||||||
sendPluginCommand("calllog", "CLOSE");
|
sendPluginCommand("calllog", "CLOSE");
|
||||||
}
|
}
|
||||||
|
if (isPidFileAlive(getRuntimeFile("xcontacts.pid"))) {
|
||||||
|
sendPluginCommand("contacts", "CLOSE");
|
||||||
|
}
|
||||||
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
if (isPidFileAlive(getRuntimeFile("xdrawer.pid"))) {
|
||||||
sendPluginCommand("xdrawer", "CLOSE");
|
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;
|
int len = 0;
|
||||||
if (strcmp(plugin_name, "xdrawer") == 0) {
|
if (strcmp(plugin_name, "xdrawer") == 0) {
|
||||||
len = snprintf(cmd, sizeof(cmd), "TOGGLE\n");
|
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]) {
|
} else if (sub_argc >= 2 && sub_argv[1] && sub_argv[1][0]) {
|
||||||
len = snprintf(cmd, sizeof(cmd), "OPEN %s\n", sub_argv[1]);
|
len = snprintf(cmd, sizeof(cmd), "OPEN %s\n", sub_argv[1]);
|
||||||
} else {
|
} 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) {
|
if (strcasecmp(base, "xcalllog") == 0 || strcasecmp(base, "calllog") == 0) {
|
||||||
return "calllog";
|
return "calllog";
|
||||||
}
|
}
|
||||||
|
if (strcasecmp(base, "xcontacts") == 0 || strcasecmp(base, "contacts") == 0) {
|
||||||
|
return "contacts";
|
||||||
|
}
|
||||||
return NULL;
|
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* kIconPhone = "\xef\x82\x95"; // U+F095 phone handset
|
||||||
constexpr const char* kIconPhoneLog = "\xef\x82\x98"; // U+F098 phone square
|
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* 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* kIconClock = "\xef\x80\x97"; // U+F017 recent clock
|
||||||
constexpr const char* kIconOutCall = "\xef\x85\xb8"; // U+F178 outgoing arrow
|
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* kIconInCall = "\xef\x85\xb5"; // U+F175 incoming arrow
|
||||||
constexpr const char* kIconMissedCall = "\xef\x81\xb1"; // U+F071 missed/alert
|
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* 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() {
|
inline int64_t nowMs() {
|
||||||
struct timespec ts {};
|
struct timespec ts {};
|
||||||
@@ -525,6 +533,176 @@ class ContactBook {
|
|||||||
return out;
|
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:
|
private:
|
||||||
std::vector<ContactEntry> saved_;
|
std::vector<ContactEntry> saved_;
|
||||||
std::unordered_map<std::string, std::string> exactMap_;
|
std::unordered_map<std::string, std::string> exactMap_;
|
||||||
|
|||||||
+60
-3
@@ -49,6 +49,7 @@
|
|||||||
#include <X11/Xlib-xcb.h>
|
#include <X11/Xlib-xcb.h>
|
||||||
#include <xcb/res.h>
|
#include <xcb/res.h>
|
||||||
#include <pango/pango.h>
|
#include <pango/pango.h>
|
||||||
|
#include <pango/pangoxft.h>
|
||||||
|
|
||||||
#include "drw.h"
|
#include "drw.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -147,6 +148,7 @@ struct Monitor {
|
|||||||
Client *stack;
|
Client *stack;
|
||||||
Monitor *next;
|
Monitor *next;
|
||||||
Window barwin;
|
Window barwin;
|
||||||
|
Window softwin;
|
||||||
const Layout *lt[2];
|
const Layout *lt[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -769,6 +771,10 @@ cleanupmon(Monitor *mon)
|
|||||||
}
|
}
|
||||||
XUnmapWindow(dpy, mon->barwin);
|
XUnmapWindow(dpy, mon->barwin);
|
||||||
XDestroyWindow(dpy, mon->barwin);
|
XDestroyWindow(dpy, mon->barwin);
|
||||||
|
if (mon->softwin) {
|
||||||
|
XUnmapWindow(dpy, mon->softwin);
|
||||||
|
XDestroyWindow(dpy, mon->softwin);
|
||||||
|
}
|
||||||
free(mon);
|
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_text(drw, MAX(x, m->ww - sw), 0, sw, bh, 0, s, 0, True);
|
||||||
}
|
}
|
||||||
drw_map(drw, m->barwin, 0, 0, m->ww, bh);
|
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
|
void
|
||||||
@@ -1806,6 +1841,10 @@ flush_pending_softkey(void)
|
|||||||
const Arg syscmd = { .v = (const char*[]){ "sxmo_appmenu.sh", "sys", NULL } };
|
const Arg syscmd = { .v = (const char*[]){ "sxmo_appmenu.sh", "sys", NULL } };
|
||||||
last_menu_pgid = spawn_pgid(&syscmd);
|
last_menu_pgid = spawn_pgid(&syscmd);
|
||||||
} else if (pending == SOFTKEY_RIGHT) {
|
} 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 } };
|
const Arg ctxcmd = { .v = (const char*[]){ "sxmo_appmenu.sh", NULL } };
|
||||||
last_menu_pgid = spawn_pgid(&ctxcmd);
|
last_menu_pgid = spawn_pgid(&ctxcmd);
|
||||||
}
|
}
|
||||||
@@ -2170,9 +2209,12 @@ propertynotify(XEvent *e)
|
|||||||
Window trans;
|
Window trans;
|
||||||
XPropertyEvent *ev = &e->xproperty;
|
XPropertyEvent *ev = &e->xproperty;
|
||||||
|
|
||||||
if ((ev->window == root) && (ev->atom == XA_WM_NAME))
|
if (ev->window == root) {
|
||||||
|
if (ev->atom == XA_WM_NAME)
|
||||||
updatestatus();
|
updatestatus();
|
||||||
else if (ev->state == PropertyDelete)
|
else
|
||||||
|
drawbars();
|
||||||
|
} else if (ev->state == PropertyDelete)
|
||||||
return; /* ignore */
|
return; /* ignore */
|
||||||
else if ((c = wintoclient(ev->window))) {
|
else if ((c = wintoclient(ev->window))) {
|
||||||
switch(ev->atom) {
|
switch(ev->atom) {
|
||||||
@@ -2902,6 +2944,21 @@ updatebars(void)
|
|||||||
};
|
};
|
||||||
XClassHint ch = {"dwm", "dwm"};
|
XClassHint ch = {"dwm", "dwm"};
|
||||||
for (m = mons; m; m = m->next) {
|
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)
|
if (m->barwin)
|
||||||
continue;
|
continue;
|
||||||
m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
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))
|
if (w == root && getrootptr(&x, &y))
|
||||||
return recttomon(x, y, 1, 1);
|
return recttomon(x, y, 1, 1);
|
||||||
for (m = mons; m; m = m->next)
|
for (m = mons; m; m = m->next)
|
||||||
if (w == m->barwin)
|
if (w == m->barwin || w == m->softwin)
|
||||||
return m;
|
return m;
|
||||||
if ((c = wintoclient(w)))
|
if ((c = wintoclient(w)))
|
||||||
return c->mon;
|
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("xdialer.pid", "/tmp/dwm_plugin_dialer.fifo");
|
||||||
closeOtherPlugin("xcalllog.pid", "/tmp/dwm_plugin_calllog.fifo");
|
closeOtherPlugin("xcalllog.pid", "/tmp/dwm_plugin_calllog.fifo");
|
||||||
|
closeOtherPlugin("xcontacts.pid", "/tmp/dwm_plugin_contacts.fifo");
|
||||||
openStartMs = nowMs();
|
openStartMs = nowMs();
|
||||||
startupIgnoreUntilMs = openStartMs + 180;
|
startupIgnoreUntilMs = openStartMs + 180;
|
||||||
initialKeysReleased = (querySoftkeysDown(dpy) == 0);
|
initialKeysReleased = (querySoftkeysDown(dpy) == 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user