Add ringtones/wallpapers plugins, AT console, dialer USSD/*#06#, and SIM icon fix
This commit is contained in:
@@ -29,7 +29,8 @@ void handleSignal(int) {
|
||||
enum class TabId {
|
||||
SimCards = 0,
|
||||
RadioInfo = 1,
|
||||
ModemLog = 2,
|
||||
AtConsole = 2,
|
||||
ModemLog = 3,
|
||||
};
|
||||
|
||||
enum class ModalMode {
|
||||
@@ -94,6 +95,8 @@ struct ModemStatusData {
|
||||
std::string accessTech;
|
||||
int signalQuality = 0;
|
||||
std::string imei;
|
||||
std::string imei2;
|
||||
std::string imeiSv;
|
||||
std::string ownNumber;
|
||||
std::string simDbusPath;
|
||||
std::string simIccid;
|
||||
@@ -126,18 +129,42 @@ struct ModemLogRow {
|
||||
std::string detail;
|
||||
};
|
||||
|
||||
std::string shellQuote(const std::string& s) {
|
||||
std::string out = "'";
|
||||
for (char c : s) {
|
||||
if (c == '\'') {
|
||||
out += "'\\''";
|
||||
} else {
|
||||
out.push_back(c);
|
||||
}
|
||||
}
|
||||
out.push_back('\'');
|
||||
return out;
|
||||
}
|
||||
constexpr const char* kAtPresets[] = {
|
||||
"AT",
|
||||
"ATI",
|
||||
"AT+CGSN",
|
||||
"AT+CSQ",
|
||||
"AT+CREG?",
|
||||
"AT+COPS?",
|
||||
"AT+CPIN?",
|
||||
"AT+CCID",
|
||||
"AT+CGDCONT?",
|
||||
"AT+CGPADDR",
|
||||
"AT+CFUN?",
|
||||
"AT+CLCC",
|
||||
};
|
||||
constexpr int kNumAtPresets =
|
||||
static_cast<int>(sizeof(kAtPresets) / sizeof(kAtPresets[0]));
|
||||
|
||||
enum class AtTextMode {
|
||||
Upper = 0, // ABC
|
||||
Lower = 1, // abc
|
||||
Num = 2, // 123
|
||||
Sym = 3, // Sym
|
||||
};
|
||||
|
||||
const char* kAtTapMap[10] = {
|
||||
" 0+=",
|
||||
"+?=,1\"':;/-_",
|
||||
"ABC2",
|
||||
"DEF3",
|
||||
"GHI4",
|
||||
"JKL5",
|
||||
"MNO6",
|
||||
"PQRS7",
|
||||
"TUV8",
|
||||
"WXYZ9"
|
||||
};
|
||||
|
||||
void parseKvLines(const std::string& text,
|
||||
std::unordered_map<std::string, std::string>& out,
|
||||
@@ -231,6 +258,11 @@ ModemStatusData queryModemAndSimStatus() {
|
||||
if (d.imei.empty()) {
|
||||
d.imei = cleanMmVal(mmKv["modem.generic.equipment-identifier"]);
|
||||
}
|
||||
DeviceImeis devImeis = queryDeviceImeis();
|
||||
if (!devImeis.imei1.empty()) d.imei = devImeis.imei1;
|
||||
if (!devImeis.imei2.empty()) d.imei2 = devImeis.imei2;
|
||||
if (!devImeis.imeiSv.empty()) d.imeiSv = devImeis.imeiSv;
|
||||
if (d.imei2.empty()) d.imei2 = d.imei;
|
||||
d.ownNumber = cleanMmVal(mmKv["modem.generic.own-numbers.value[1]"]);
|
||||
d.simDbusPath = cleanMmVal(mmKv["modem.generic.sim"]);
|
||||
d.currentModes = cleanMmVal(mmKv["modem.generic.current-modes"]);
|
||||
@@ -452,6 +484,18 @@ int runModemApp(int argc, char** argv) {
|
||||
std::string ussdResponse;
|
||||
bool ussdWaitingReply = false;
|
||||
|
||||
// AT Console state
|
||||
int atFocusRow = 0; // 0 = Input, 1 = Preset/Port, 2 = Output scroll
|
||||
int atPresetIdx = 0;
|
||||
int atPortIdx = 0; // 0 = auto, 1 = wwan0at0, 2 = wwan0at1
|
||||
std::string atInput = "AT";
|
||||
std::string atOutput = "Enter an AT command and press Send.\nUse Preset row (< >) for common commands.";
|
||||
int atScrollLine = 0;
|
||||
AtTextMode atTextMode = AtTextMode::Upper;
|
||||
int atLastTapKey = -1;
|
||||
int atLastTapIdx = 0;
|
||||
int64_t atLastTapMs = 0;
|
||||
|
||||
std::string statusBanner;
|
||||
int64_t statusBannerUntilMs = 0;
|
||||
|
||||
@@ -517,6 +561,8 @@ int runModemApp(int argc, char** argv) {
|
||||
activeTab = TabId::ModemLog;
|
||||
book.load();
|
||||
logRows = loadRecentModemLog(book);
|
||||
} else if (a == "at" || a == "atcmd") {
|
||||
activeTab = TabId::AtConsole;
|
||||
} else if (a == "ussd") {
|
||||
activeTab = TabId::RadioInfo;
|
||||
modal = ModalMode::UssdDialog;
|
||||
@@ -604,9 +650,9 @@ int runModemApp(int argc, char** argv) {
|
||||
XSetForeground(dpy, gc, pt.spec.border);
|
||||
XDrawLine(dpy, pix, gc, 0, 29, kWinWidth, 29);
|
||||
|
||||
const char* tabLabels[3] = {"1:SIMs", "2:Radio", "3:Log"};
|
||||
int tabW = kWinWidth / 3;
|
||||
for (int t = 0; t < 3; ++t) {
|
||||
const char* tabLabels[4] = {"1:SIMs", "2:Radio", "3:AT", "4:Log"};
|
||||
int tabW = kWinWidth / 4;
|
||||
for (int t = 0; t < 4; ++t) {
|
||||
bool isSel = (static_cast<int>(activeTab) == t);
|
||||
if (isSel) {
|
||||
XSetForeground(dpy, gc, pt.spec.selBg);
|
||||
@@ -742,12 +788,11 @@ int runModemApp(int argc, char** argv) {
|
||||
(status.primaryGwSlot > 0 ? std::to_string(status.primaryGwSlot) : "--");
|
||||
drawPango(layoutSmall, &colLight, 10, contentY + 42, 18, sigLine, 220);
|
||||
|
||||
std::string imeiLine = "IMEI: " + (status.imei.empty() ? "--" : status.imei);
|
||||
drawPango(layoutSmall, &colMuted, 10, contentY + 60, 18, imeiLine, 220);
|
||||
std::string imei1Line = "IMEI 1: " + (status.imei.empty() ? "--" : status.imei);
|
||||
drawPango(layoutSmall, &colMuted, 10, contentY + 60, 18, imei1Line, 220);
|
||||
|
||||
std::string iccidLine = "ICCID: " +
|
||||
(status.simIccid.empty() ? "--" : status.simIccid);
|
||||
drawPango(layoutSmall, &colMuted, 10, contentY + 78, 18, iccidLine, 220);
|
||||
std::string imei2Line = "IMEI 2: " + (status.imei2.empty() ? "--" : status.imei2);
|
||||
drawPango(layoutSmall, &colMuted, 10, contentY + 78, 18, imei2Line, 220);
|
||||
|
||||
// 5 Interactive Radio Control Rows
|
||||
std::string modeLabel = kRadioModes[status.modePresetIdx].label;
|
||||
@@ -772,6 +817,75 @@ int runModemApp(int argc, char** argv) {
|
||||
}
|
||||
|
||||
drawSoftkeyBar("Refresh", "Apply", "Close");
|
||||
} else if (activeTab == TabId::AtConsole) {
|
||||
const char* modeBadge = "[ABC]";
|
||||
if (atTextMode == AtTextMode::Lower) modeBadge = "[abc]";
|
||||
else if (atTextMode == AtTextMode::Num) modeBadge = "[123]";
|
||||
else if (atTextMode == AtTextMode::Sym) modeBadge = "[Sym]";
|
||||
|
||||
const char* portNames[3] = {"auto", "wwan0at0", "wwan0at1"};
|
||||
const char* portLabels[3] = {"Auto", "SIM1 (at0)", "SIM2 (at1)"};
|
||||
(void)portNames;
|
||||
|
||||
// Row 0: AT Command Input Box (Y=contentY..contentY+46)
|
||||
drawPango(layoutSmall, &colYellow, 8, contentY, 18,
|
||||
std::string(kIconTerm) + " AT Command (# mode, * +?=):");
|
||||
int mbW = pangoTextWidth(layoutSmall, modeBadge);
|
||||
drawPango(layoutSmall, &colGreen, kWinWidth - mbW - 8, contentY, 18, modeBadge);
|
||||
|
||||
bool focus0 = (atFocusRow == 0);
|
||||
XSetForeground(dpy, gc, focus0 ? pt.spec.bgInputFocus : pt.spec.bgAltEven);
|
||||
XFillRectangle(dpy, pix, gc, 6, contentY + 19, kWinWidth - 12, 26);
|
||||
XSetForeground(dpy, gc, focus0 ? pt.spec.accent : pt.spec.border);
|
||||
XDrawRectangle(dpy, pix, gc, 6, contentY + 19, kWinWidth - 13, 25);
|
||||
drawPango(layoutMain, &colWhite, 12, contentY + 19, 26,
|
||||
atInput + (focus0 ? "_" : ""), kWinWidth - 24);
|
||||
|
||||
// Row 1: Preset & AT Port Selector (Y=contentY+49..contentY+73)
|
||||
bool focus1 = (atFocusRow == 1);
|
||||
XSetForeground(dpy, gc, focus1 ? pt.spec.selBg : pt.spec.bgAltOdd);
|
||||
XFillRectangle(dpy, pix, gc, 6, contentY + 48, kWinWidth - 12, 24);
|
||||
std::string presetRow = "< Preset: " + std::string(kAtPresets[atPresetIdx]) +
|
||||
" | *Port: " + portLabels[atPortIdx] + " >";
|
||||
drawPango(layoutSmall, focus1 ? &colWhite : &colLight,
|
||||
10, contentY + 48, 24, presetRow, kWinWidth - 20);
|
||||
|
||||
// Row 2: AT Response Output Area (Y=contentY+75..contentY+contentH-2)
|
||||
bool focus2 = (atFocusRow == 2);
|
||||
int outY = contentY + 75;
|
||||
int outH = contentH - 77;
|
||||
XSetForeground(dpy, gc, pt.spec.bgAltEven);
|
||||
XFillRectangle(dpy, pix, gc, 6, outY, kWinWidth - 12, outH);
|
||||
XSetForeground(dpy, gc, focus2 ? pt.spec.accent : pt.spec.border);
|
||||
XDrawRectangle(dpy, pix, gc, 6, outY, kWinWidth - 13, outH - 1);
|
||||
|
||||
pango_layout_set_width(layoutSmall, (kWinWidth - 24) * PANGO_SCALE);
|
||||
pango_layout_set_wrap(layoutSmall, PANGO_WRAP_WORD_CHAR);
|
||||
pango_layout_set_ellipsize(layoutSmall, PANGO_ELLIPSIZE_NONE);
|
||||
pango_layout_set_text(layoutSmall, atOutput.c_str(),
|
||||
static_cast<int>(atOutput.size()));
|
||||
int lineCount = pango_layout_get_line_count(layoutSmall);
|
||||
int maxVisLines = std::max(1, (outH - 8) / 17);
|
||||
if (atScrollLine > std::max(0, lineCount - maxVisLines)) {
|
||||
atScrollLine = std::max(0, lineCount - maxVisLines);
|
||||
}
|
||||
int curY = outY + 4;
|
||||
for (int li = atScrollLine;
|
||||
li < lineCount && (li - atScrollLine) < maxVisLines; ++li) {
|
||||
PangoLayoutLine* pl = pango_layout_get_line_readonly(layoutSmall, li);
|
||||
if (pl) {
|
||||
PangoRectangle ink{}, logical{};
|
||||
pango_layout_line_get_pixel_extents(pl, &ink, &logical);
|
||||
pango_xft_render_layout_line(
|
||||
xftDraw, &colLight, pl, 12 * PANGO_SCALE,
|
||||
(curY - logical.y) * PANGO_SCALE);
|
||||
curY += std::max(16, logical.height + 1);
|
||||
}
|
||||
}
|
||||
pango_layout_set_width(layoutSmall, -1);
|
||||
|
||||
drawSoftkeyBar("Send", "Send",
|
||||
(atFocusRow == 0 && !atInput.empty()) ? "Clear" : "Close");
|
||||
} else if (activeTab == TabId::ModemLog) {
|
||||
if (logRows.empty()) {
|
||||
drawPango(layoutMain, &colMuted, 16, contentY + 60, 24,
|
||||
@@ -1144,16 +1258,17 @@ int runModemApp(int argc, char** argv) {
|
||||
}
|
||||
} else if (modal == ModalMode::UssdDialog) {
|
||||
if (ussdInput.empty()) return;
|
||||
ussdResponse = "Sending USSD request...";
|
||||
if (ussdInput == "*#06#") {
|
||||
DeviceImeis im = queryDeviceImeis();
|
||||
ussdResponse = "IMEI 1: " + (im.imei1.empty() ? "--" : im.imei1) +
|
||||
"\nIMEI 2: " + (im.imei2.empty() ? "--" : im.imei2) +
|
||||
"\nIMEI SV: " + (im.imeiSv.empty() ? "--" : im.imeiSv);
|
||||
ussdWaitingReply = false;
|
||||
return;
|
||||
}
|
||||
ussdResponse = "Sending USSD " + ussdInput + "...";
|
||||
render();
|
||||
std::string cmd = ussdWaitingReply
|
||||
? ("mmcli -m any --3gpp-ussd-respond=" + shellQuote(ussdInput) + " 2>&1")
|
||||
: ("mmcli -m any --3gpp-ussd-initiate=" + shellQuote(ussdInput) + " 2>&1");
|
||||
int rc = 0;
|
||||
std::string out = trimStr(runCaptureCmd(cmd, &rc));
|
||||
ussdResponse = out.empty() ? "(No response)" : out;
|
||||
std::string stOut = runCaptureCmd("mmcli -m any --3gpp-ussd-status -K 2>/dev/null");
|
||||
ussdWaitingReply = (stOut.find("user-response") != std::string::npos);
|
||||
ussdResponse = sendModemUssd(ussdInput, ussdWaitingReply, &ussdWaitingReply);
|
||||
if (ussdWaitingReply) {
|
||||
ussdInput.clear();
|
||||
}
|
||||
@@ -1212,6 +1327,30 @@ int runModemApp(int argc, char** argv) {
|
||||
}
|
||||
};
|
||||
|
||||
auto executeAtCommand = [&]() {
|
||||
std::string cmd = trimStr(atInput);
|
||||
if (cmd.empty()) {
|
||||
setBanner("AT command cannot be empty");
|
||||
return;
|
||||
}
|
||||
const char* portArg = (atPortIdx == 1)
|
||||
? "/dev/wwan0at0"
|
||||
: (atPortIdx == 2 ? "/dev/wwan0at1" : "auto");
|
||||
atOutput = "Sending: " + cmd + " ...";
|
||||
atScrollLine = 0;
|
||||
render();
|
||||
std::string out = trimStr(runCaptureCmd(
|
||||
"doas -n /usr/libexec/msm-modem-uim-selection at " +
|
||||
shellQuote(portArg) + " " + shellQuote(cmd) + " 2>&1"));
|
||||
if (out.empty()) {
|
||||
atOutput = "> " + cmd + "\n(No response)";
|
||||
} else {
|
||||
atOutput = "> " + cmd + "\n" + out;
|
||||
}
|
||||
atScrollLine = 0;
|
||||
setBanner("AT response received");
|
||||
};
|
||||
|
||||
auto handleLeftSoftkey = [&]() {
|
||||
if (modal == ModalMode::SimActions) {
|
||||
int act = actionSel;
|
||||
@@ -1256,6 +1395,8 @@ int runModemApp(int argc, char** argv) {
|
||||
} else if (activeTab == TabId::RadioInfo) {
|
||||
refreshData(false);
|
||||
setBanner("Modem status refreshed");
|
||||
} else if (activeTab == TabId::AtConsole) {
|
||||
executeAtCommand();
|
||||
} else if (activeTab == TabId::ModemLog) {
|
||||
refreshData(true);
|
||||
setBanner("Modem log refreshed");
|
||||
@@ -1312,6 +1453,12 @@ int runModemApp(int argc, char** argv) {
|
||||
refreshData(false);
|
||||
setBanner("Refreshed");
|
||||
}
|
||||
} else if (activeTab == TabId::AtConsole) {
|
||||
if (atFocusRow == 1) {
|
||||
atPortIdx = (atPortIdx + 1) % 3;
|
||||
} else {
|
||||
executeAtCommand();
|
||||
}
|
||||
} else if (activeTab == TabId::ModemLog) {
|
||||
if (!logRows.empty() && logRowSel >= 0 &&
|
||||
logRowSel < static_cast<int>(logRows.size())) {
|
||||
@@ -1474,8 +1621,84 @@ int runModemApp(int argc, char** argv) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Main View Navigation
|
||||
// AT Console text input when atFocusRow == 0
|
||||
char dch = mapDialKey(sym, kc, ev.xkey.state);
|
||||
if (activeTab == TabId::AtConsole && atFocusRow == 0) {
|
||||
if (sym == XK_BackSpace || sym == XK_Delete) {
|
||||
if (!atInput.empty()) {
|
||||
atInput.pop_back();
|
||||
atLastTapKey = -1;
|
||||
render();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (dch == '#') {
|
||||
atTextMode = static_cast<AtTextMode>(
|
||||
(static_cast<int>(atTextMode) + 1) % 4);
|
||||
atLastTapKey = -1;
|
||||
render();
|
||||
continue;
|
||||
}
|
||||
if (dch == '*') {
|
||||
const char* syms = "+?=,1\"':;/-_*#";
|
||||
int len = static_cast<int>(std::strlen(syms));
|
||||
if (atLastTapKey == 10 && (now - atLastTapMs) < 850 &&
|
||||
!atInput.empty()) {
|
||||
atLastTapIdx = (atLastTapIdx + 1) % len;
|
||||
atInput.back() = syms[atLastTapIdx];
|
||||
} else if (atInput.size() < 64) {
|
||||
atLastTapKey = 10;
|
||||
atLastTapIdx = 0;
|
||||
atInput.push_back(syms[0]);
|
||||
}
|
||||
atLastTapMs = now;
|
||||
render();
|
||||
continue;
|
||||
}
|
||||
if (dch >= '0' && dch <= '9') {
|
||||
int digit = dch - '0';
|
||||
if (atTextMode == AtTextMode::Num) {
|
||||
if (atInput.size() < 64) {
|
||||
atInput.push_back(dch);
|
||||
atLastTapKey = -1;
|
||||
}
|
||||
} else if (atTextMode == AtTextMode::Sym) {
|
||||
const char* symTable = "+?=,.\"':;/-_";
|
||||
char sc = symTable[digit % 10];
|
||||
if (atInput.size() < 64) {
|
||||
atInput.push_back(sc);
|
||||
atLastTapKey = -1;
|
||||
}
|
||||
} else {
|
||||
const char* seq = kAtTapMap[digit];
|
||||
int len = static_cast<int>(std::strlen(seq));
|
||||
if (atLastTapKey == digit && (now - atLastTapMs) < 850 &&
|
||||
!atInput.empty()) {
|
||||
atLastTapIdx = (atLastTapIdx + 1) % len;
|
||||
char chOut = seq[atLastTapIdx];
|
||||
if (atTextMode == AtTextMode::Lower) {
|
||||
chOut = static_cast<char>(
|
||||
std::tolower(static_cast<unsigned char>(chOut)));
|
||||
}
|
||||
atInput.back() = chOut;
|
||||
} else if (atInput.size() < 64) {
|
||||
atLastTapKey = digit;
|
||||
atLastTapIdx = 0;
|
||||
char chOut = seq[0];
|
||||
if (atTextMode == AtTextMode::Lower) {
|
||||
chOut = static_cast<char>(
|
||||
std::tolower(static_cast<unsigned char>(chOut)));
|
||||
}
|
||||
atInput.push_back(chOut);
|
||||
}
|
||||
atLastTapMs = now;
|
||||
}
|
||||
render();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Main View Navigation (4 tabs: 1:SIMs, 2:Radio, 3:AT, 4:Log)
|
||||
if (dch == '1') {
|
||||
activeTab = TabId::SimCards;
|
||||
render();
|
||||
@@ -1485,25 +1708,39 @@ int runModemApp(int argc, char** argv) {
|
||||
render();
|
||||
continue;
|
||||
} else if (dch == '3') {
|
||||
activeTab = TabId::AtConsole;
|
||||
render();
|
||||
continue;
|
||||
} else if (dch == '4') {
|
||||
activeTab = TabId::ModemLog;
|
||||
refreshData(true);
|
||||
render();
|
||||
continue;
|
||||
} else if (activeTab == TabId::AtConsole && dch == '*') {
|
||||
atPortIdx = (atPortIdx + 1) % 3;
|
||||
render();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sym == XK_Left || sym == XK_KP_Left) {
|
||||
if (activeTab == TabId::RadioInfo && radioRowSel == 0) {
|
||||
applyRadioModePreset(status.modePresetIdx - 1);
|
||||
} else if (activeTab == TabId::AtConsole && atFocusRow == 1) {
|
||||
atPresetIdx = (atPresetIdx + kNumAtPresets - 1) % kNumAtPresets;
|
||||
atInput = kAtPresets[atPresetIdx];
|
||||
} else {
|
||||
activeTab = static_cast<TabId>((static_cast<int>(activeTab) + 2) % 3);
|
||||
activeTab = static_cast<TabId>((static_cast<int>(activeTab) + 3) % 4);
|
||||
if (activeTab == TabId::ModemLog) refreshData(true);
|
||||
}
|
||||
render();
|
||||
} else if (sym == XK_Right || sym == XK_KP_Right) {
|
||||
if (activeTab == TabId::RadioInfo && radioRowSel == 0) {
|
||||
applyRadioModePreset(status.modePresetIdx + 1);
|
||||
} else if (activeTab == TabId::AtConsole && atFocusRow == 1) {
|
||||
atPresetIdx = (atPresetIdx + 1) % kNumAtPresets;
|
||||
atInput = kAtPresets[atPresetIdx];
|
||||
} else {
|
||||
activeTab = static_cast<TabId>((static_cast<int>(activeTab) + 1) % 3);
|
||||
activeTab = static_cast<TabId>((static_cast<int>(activeTab) + 1) % 4);
|
||||
if (activeTab == TabId::ModemLog) refreshData(true);
|
||||
}
|
||||
render();
|
||||
@@ -1512,6 +1749,12 @@ int runModemApp(int argc, char** argv) {
|
||||
simRowSel = (simRowSel + 5) % 6;
|
||||
} else if (activeTab == TabId::RadioInfo) {
|
||||
radioRowSel = (radioRowSel + 4) % 5;
|
||||
} else if (activeTab == TabId::AtConsole) {
|
||||
if (atFocusRow == 2 && atScrollLine > 0) {
|
||||
--atScrollLine;
|
||||
} else {
|
||||
atFocusRow = (atFocusRow + 2) % 3;
|
||||
}
|
||||
} else if (activeTab == TabId::ModemLog && !logRows.empty()) {
|
||||
logRowSel = std::max(0, logRowSel - 1);
|
||||
}
|
||||
@@ -1521,11 +1764,19 @@ int runModemApp(int argc, char** argv) {
|
||||
simRowSel = (simRowSel + 1) % 6;
|
||||
} else if (activeTab == TabId::RadioInfo) {
|
||||
radioRowSel = (radioRowSel + 1) % 5;
|
||||
} else if (activeTab == TabId::AtConsole) {
|
||||
if (atFocusRow == 2) {
|
||||
++atScrollLine;
|
||||
} else {
|
||||
atFocusRow = (atFocusRow + 1) % 3;
|
||||
}
|
||||
} else if (activeTab == TabId::ModemLog && !logRows.empty()) {
|
||||
logRowSel = std::min(static_cast<int>(logRows.size()) - 1, logRowSel + 1);
|
||||
}
|
||||
render();
|
||||
} else if (sym == XK_Return || sym == XK_KP_Enter) {
|
||||
} else if (sym == XK_Return || sym == XK_KP_Enter ||
|
||||
sym == XF86XK_Send || sym == XF86XK_Phone ||
|
||||
sym == XF86XK_PickupPhone) {
|
||||
handleEnterKey();
|
||||
render();
|
||||
}
|
||||
@@ -1565,7 +1816,8 @@ int runModemApp(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
// Periodic 5-second status refresh while visible on SIM/Radio tabs
|
||||
if (modal == ModalMode::None && activeTab != TabId::ModemLog) {
|
||||
if (modal == ModalMode::None && activeTab != TabId::ModemLog &&
|
||||
activeTab != TabId::AtConsole) {
|
||||
int64_t rRem = (lastRefreshMs + 5000) - now;
|
||||
if (rRem <= 0) {
|
||||
refreshData(false);
|
||||
|
||||
Reference in New Issue
Block a user