From f6c150a8c824b794852f9a743d60b8b77dd6c6aa Mon Sep 17 00:00:00 2001 From: reionwong Date: Sat, 17 Oct 2026 10:11:04 +0800 Subject: [PATCH] fix(settings): keep the typed proxy ports when a new server is saved with them --- src/pages/network/proxy/proxypage.cpp | 6 +++ src/pages/network/proxy/proxysettings.cpp | 9 +++- src/pages/network/proxy/proxysettings.h | 2 + tests/ui/network_proxy_test.cpp | 60 +++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/pages/network/proxy/proxypage.cpp b/src/pages/network/proxy/proxypage.cpp index 2930f01..738f773 100644 --- a/src/pages/network/proxy/proxypage.cpp +++ b/src/pages/network/proxy/proxypage.cpp @@ -200,6 +200,9 @@ private: void reload(unsigned fields) { + // The page's own values coming back while it saves them. + if (m_saving) + return; if (fields & NetworkProxy::FlagField) { const int flag = m_proxy.flag(); m_noProxy->setChecked(flag == 0); @@ -231,6 +234,7 @@ private: void saveFields() { m_needSave = false; + m_saving = true; m_proxy.setScriptProxy(m_script->text()); m_proxy.setHttpProxy(m_http->text()); m_proxy.setHttpProxyPort(m_httpPort->text()); @@ -239,6 +243,7 @@ private: m_proxy.setFtpProxyPort(m_ftpPort->text()); m_proxy.setSocksProxy(m_socks->text()); m_proxy.setSocksProxyPort(m_socksPort->text()); + m_saving = false; update(); } @@ -257,6 +262,7 @@ private: cutefish::base::Subscription m_subscription; ButtonGroup m_modes; bool m_needSave = false; + bool m_saving = false; RadioButton* m_noProxy; RadioButton* m_auto; RadioButton* m_manual; diff --git a/src/pages/network/proxy/proxysettings.cpp b/src/pages/network/proxy/proxysettings.cpp index 1c7b72f..4f336f4 100644 --- a/src/pages/network/proxy/proxysettings.cpp +++ b/src/pages/network/proxy/proxysettings.cpp @@ -227,9 +227,16 @@ static void skipSpaces(const std::string& text, size_t& pos) namespace gsettings { +static std::string s_path; + std::string path() { - return cutefish::base::paths::configHome() + "/glib-2.0/settings/keyfile"; + return s_path.empty() ? cutefish::base::paths::configHome() + "/glib-2.0/settings/keyfile" : s_path; +} + +void setPath(std::string path) +{ + s_path = std::move(path); } std::string toString(const std::string& text, const std::string& fallback) diff --git a/src/pages/network/proxy/proxysettings.h b/src/pages/network/proxy/proxysettings.h index ea8ba3f..057aade 100644 --- a/src/pages/network/proxy/proxysettings.h +++ b/src/pages/network/proxy/proxysettings.h @@ -32,6 +32,8 @@ bool writeGroup(const std::string& path, const std::string& group, const Group& namespace gsettings { std::string path(); +// Points path() at another file; tests keep the session's own untouched. +void setPath(std::string path); std::string toString(const std::string& text, const std::string& fallback = {}); int toInt(const std::string& text, int fallback); bool toBool(const std::string& text, bool fallback); diff --git a/tests/ui/network_proxy_test.cpp b/tests/ui/network_proxy_test.cpp index 224aa8e..aac8c5f 100644 --- a/tests/ui/network_proxy_test.cpp +++ b/tests/ui/network_proxy_test.cpp @@ -9,9 +9,16 @@ #include #include +#include "input_test_support.h" +#include "pagetest.h" #include "pages/network/common/textchecks.h" #include "pages/network/proxy/proxysettings.h" +#include "ui/button.h" +#include "ui/test_input.h" +#include "ui/text_field.h" +#include "window/page.h" +using namespace cutefish::ui; using namespace settings::network; namespace { @@ -45,6 +52,21 @@ struct KeyFile : testing::Test std::string path; }; +template +void findAll(View* view, std::vector* found) +{ + if (auto* match = dynamic_cast(view)) + found->push_back(match); + for (const auto& child : view->children()) + findAll(child.get(), found); +} + +PointF centre(View* view) +{ + const PointF origin = view->mapToWindow({0, 0}); + return {origin.x + view->geometry().width / 2, origin.y + view->geometry().height / 2}; +} + } // namespace TEST_F(KeyFile, ReadsGroupsAndKeys) @@ -103,3 +125,41 @@ TEST(EditFieldText, PortsAndNumbers) EXPECT_TRUE(isNumberText("10", 10)); EXPECT_FALSE(isNumberText("11", 10)); } + +// A new server and its port saved together: the server going in first must +// not put the old port back into the field before it is read. +TEST_F(KeyFile, ANewServerKeepsTheTypedPort) +{ + write("[system/proxy]\nmode='manual'\n"); + gsettings::setPath(path); + { + PageFixture page("network", "proxy"); + Window& window = page.window->window(); + std::vector fields; + findAll(page.window->currentPage(), &fields); + // The script URL, then HTTP, FTP and SOCKS, each with its port. + ASSERT_EQ(fields.size(), 7u); + const std::vector typed = {"", "http.test", "3128", "", "", "socks.test", "1081"}; + for (size_t i = 0; i < fields.size(); ++i) { + if (typed[i].empty()) + continue; + window.grab(); + TestInput::click(window, centre(fields[i])); + TestInput::typeText(window, typed[i]); + ASSERT_EQ(fields[i]->text(), typed[i]); + } + + std::vector buttons; + findAll