Allow disabling even system proxy settings.

Fixes #4944.
This commit is contained in:
John Preston 2018-11-05 17:58:24 +04:00
parent ef64d9c188
commit e482f041a8
17 changed files with 151 additions and 78 deletions

View File

@ -491,7 +491,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_connection_save" = "Save";
"lng_proxy_settings" = "Proxy settings";
"lng_proxy_use" = "Use proxy";
"lng_proxy_disable" = "Disable proxy";
"lng_proxy_use_system_settings" = "Use system proxy settings";
"lng_proxy_use_custom" = "Use custom proxy";
"lng_proxy_use_for_calls" = "Use proxy for calls";
"lng_proxy_about" = "Proxy servers may be helpful in accessing Telegram if there is no connection in a specific region.";
"lng_proxy_add" = "Add proxy";

View File

@ -195,11 +195,8 @@ void ApiWrap::refreshProxyPromotion() {
getProxyPromotionDelayed(now, next);
return;
}
const auto proxy = Global::UseProxy()
? Global::SelectedProxy()
: ProxyData();
const auto key = [&]() -> std::pair<QString, uint32> {
if (!Global::UseProxy()) {
if (Global::ProxySettings() != ProxyData::Settings::Enabled) {
return {};
}
const auto &proxy = Global::SelectedProxy();

View File

@ -362,7 +362,7 @@ void Application::refreshGlobalProxy() {
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
const auto proxy = [&] {
if (Global::started()) {
return Global::UseProxy()
return (Global::ProxySettings() == ProxyData::Settings::Enabled)
? Global::SelectedProxy()
: ProxyData();
}
@ -372,8 +372,11 @@ void Application::refreshGlobalProxy() {
|| proxy.type == ProxyData::Type::Http) {
QNetworkProxy::setApplicationProxy(
ToNetworkProxy(ToDirectIpProxy(proxy)));
} else {
} else if (!Global::started()
|| Global::ProxySettings() == ProxyData::Settings::System) {
QNetworkProxyFactory::setUseSystemConfiguration(true);
} else {
QNetworkProxy::setApplicationProxy(QNetworkProxy::NoProxy);
}
#endif // TDESKTOP_DISABLE_NETWORK_PROXY
}

View File

@ -110,7 +110,7 @@ private:
not_null<ProxiesBoxController*> _controller;
QPointer<Ui::Checkbox> _tryIPv6;
QPointer<Ui::Checkbox> _useProxy;
std::shared_ptr<Ui::RadioenumGroup<ProxyData::Settings>> _proxySettings;
QPointer<Ui::SlideWrap<Ui::Checkbox>> _proxyForCalls;
QPointer<Ui::DividerLabel> _about;
base::unique_qptr<Ui::RpWidget> _noRows;
@ -504,10 +504,29 @@ void ProxiesBox::setupContent() {
lang(lng_connection_try_ipv6),
Global::TryIPv6()),
st::proxyTryIPv6Padding);
_useProxy = inner->add(
object_ptr<Ui::Checkbox>(
_proxySettings
= std::make_shared<Ui::RadioenumGroup<ProxyData::Settings>>(
Global::ProxySettings());
inner->add(
object_ptr<Ui::Radioenum<ProxyData::Settings>>(
inner,
lang(lng_proxy_use)),
_proxySettings,
ProxyData::Settings::Disabled,
lang(lng_proxy_disable)),
st::proxyUsePadding);
inner->add(
object_ptr<Ui::Radioenum<ProxyData::Settings>>(
inner,
_proxySettings,
ProxyData::Settings::System,
lang(lng_proxy_use_system_settings)),
st::proxyUsePadding);
inner->add(
object_ptr<Ui::Radioenum<ProxyData::Settings>>(
inner,
_proxySettings,
ProxyData::Settings::Enabled,
lang(lng_proxy_use_custom)),
st::proxyUsePadding);
_proxyForCalls = inner->add(
object_ptr<Ui::SlideWrap<Ui::Checkbox>>(
@ -543,9 +562,9 @@ void ProxiesBox::setupContent() {
inner,
st::proxyRowPadding.bottom()));
subscribe(_useProxy->checkedChanged, [=](bool checked) {
if (!_controller->setProxyEnabled(checked)) {
_useProxy->setChecked(false);
_proxySettings->setChangedCallback([=](ProxyData::Settings value) {
if (!_controller->setProxySettings(value)) {
_proxySettings->setValue(Global::ProxySettings());
addNewProxy();
}
refreshProxyForCalls();
@ -553,11 +572,11 @@ void ProxiesBox::setupContent() {
subscribe(_tryIPv6->checkedChanged, [=](bool checked) {
_controller->setTryIPv6(checked);
});
_controller->proxyEnabledValue(
) | rpl::start_with_next([=](bool enabled) {
_useProxy->setChecked(enabled);
}, _useProxy->lifetime());
_useProxy->finishAnimating();
_controller->proxySettingsValue(
) | rpl::start_with_next([=](ProxyData::Settings value) {
_proxySettings->setValue(value);
}, inner->lifetime());
subscribe(_proxyForCalls->entity()->checkedChanged, [=](bool checked) {
_controller->setProxyForCalls(checked);
});
@ -588,7 +607,8 @@ void ProxiesBox::refreshProxyForCalls() {
return;
}
_proxyForCalls->toggle(
_useProxy->checked() && _currentProxySupportsCallsId != 0,
(_proxySettings->value() == ProxyData::Settings::Enabled
&& _currentProxySupportsCallsId != 0),
anim::type::normal);
}
@ -1032,7 +1052,7 @@ ProxiesBoxController::ProxiesBoxController()
}) | ranges::to_vector;
subscribe(Global::RefConnectionTypeChanged(), [=] {
_proxyEnabledChanges.fire_copy(Global::UseProxy());
_proxySettingsChanges.fire_copy(Global::ProxySettings());
const auto i = findByProxy(Global::SelectedProxy());
if (i != end(_list)) {
updateView(*i);
@ -1074,7 +1094,9 @@ void ProxiesBoxController::ShowApplyConfirmation(
if (ranges::find(proxies, proxy) == end(proxies)) {
proxies.push_back(proxy);
}
Messenger::Instance().setCurrentProxy(proxy, true);
Messenger::Instance().setCurrentProxy(
proxy,
ProxyData::Settings::Enabled);
Local::writeSettings();
if (const auto strong = box->data()) {
strong->closeBox();
@ -1083,9 +1105,10 @@ void ProxiesBoxController::ShowApplyConfirmation(
}
}
rpl::producer<bool> ProxiesBoxController::proxyEnabledValue() const {
return _proxyEnabledChanges.events_starting_with_copy(
Global::UseProxy()
auto ProxiesBoxController::proxySettingsValue() const
-> rpl::producer<ProxyData::Settings> {
return _proxySettingsChanges.events_starting_with_copy(
Global::ProxySettings()
) | rpl::distinct_until_changed();
}
@ -1227,7 +1250,8 @@ void ProxiesBoxController::shareItem(int id) {
void ProxiesBoxController::applyItem(int id) {
auto item = findById(id);
if (Global::UseProxy() && Global::SelectedProxy() == item->data) {
if ((Global::ProxySettings() == ProxyData::Settings::Enabled)
&& Global::SelectedProxy() == item->data) {
return;
} else if (item->deleted) {
return;
@ -1235,7 +1259,9 @@ void ProxiesBoxController::applyItem(int id) {
auto j = findByProxy(Global::SelectedProxy());
Messenger::Instance().setCurrentProxy(item->data, true);
Messenger::Instance().setCurrentProxy(
item->data,
ProxyData::Settings::Enabled);
saveDelayed();
if (j != end(_list)) {
@ -1254,11 +1280,11 @@ void ProxiesBoxController::setDeleted(int id, bool deleted) {
if (item->data == Global::SelectedProxy()) {
_lastSelectedProxy = base::take(Global::RefSelectedProxy());
if (Global::UseProxy()) {
if (Global::ProxySettings() == ProxyData::Settings::Enabled) {
_lastSelectedProxyUsed = true;
Messenger::Instance().setCurrentProxy(
ProxyData(),
false);
ProxyData::Settings::System);
saveDelayed();
} else {
_lastSelectedProxyUsed = false;
@ -1278,12 +1304,12 @@ void ProxiesBoxController::setDeleted(int id, bool deleted) {
}
if (!Global::SelectedProxy() && _lastSelectedProxy == item->data) {
Assert(!Global::UseProxy());
Assert(Global::ProxySettings() != ProxyData::Settings::Enabled);
if (base::take(_lastSelectedProxyUsed)) {
Messenger::Instance().setCurrentProxy(
base::take(_lastSelectedProxy),
true);
ProxyData::Settings::Enabled);
} else {
Global::SetSelectedProxy(base::take(_lastSelectedProxy));
}
@ -1372,10 +1398,10 @@ void ProxiesBoxController::addNewItem(const ProxyData &proxy) {
applyItem(_list.back().id);
}
bool ProxiesBoxController::setProxyEnabled(bool enabled) {
if (Global::UseProxy() == enabled) {
bool ProxiesBoxController::setProxySettings(ProxyData::Settings value) {
if (Global::ProxySettings() == value) {
return true;
} else if (enabled) {
} else if (value == ProxyData::Settings::Enabled) {
if (Global::ProxiesList().empty()) {
return false;
} else if (!Global::SelectedProxy()) {
@ -1388,7 +1414,7 @@ bool ProxiesBoxController::setProxyEnabled(bool enabled) {
}
Messenger::Instance().setCurrentProxy(
Global::SelectedProxy(),
enabled);
value);
saveDelayed();
return true;
}
@ -1398,7 +1424,8 @@ void ProxiesBoxController::setProxyForCalls(bool enabled) {
return;
}
Global::SetUseProxyForCalls(enabled);
if (Global::UseProxy() && Global::SelectedProxy().supportsCalls()) {
if ((Global::ProxySettings() == ProxyData::Settings::Enabled)
&& Global::SelectedProxy().supportsCalls()) {
Global::RefConnectionTypeChanged().notify();
}
saveDelayed();
@ -1438,7 +1465,8 @@ void ProxiesBoxController::updateView(const Item &item) {
Unexpected("Proxy type in ProxiesBoxController::updateView.");
}();
const auto state = [&] {
if (!selected || !Global::UseProxy()) {
if (!selected
|| (Global::ProxySettings() != ProxyData::Settings::Enabled)) {
return item.state;
} else if (MTP::dcstate() == MTP::ConnectedState) {
return ItemState::Online;

View File

@ -74,10 +74,10 @@ public:
void applyItem(int id);
object_ptr<BoxContent> editItemBox(int id);
object_ptr<BoxContent> addNewItemBox();
bool setProxyEnabled(bool enabled);
bool setProxySettings(ProxyData::Settings value);
void setProxyForCalls(bool enabled);
void setTryIPv6(bool enabled);
rpl::producer<bool> proxyEnabledValue() const;
rpl::producer<ProxyData::Settings> proxySettingsValue() const;
rpl::producer<ItemView> views() const;
@ -117,7 +117,7 @@ private:
std::vector<Item> _list;
rpl::event_stream<ItemView> _views;
base::Timer _saveTimer;
rpl::event_stream<bool> _proxyEnabledChanges;
rpl::event_stream<ProxyData::Settings> _proxySettingsChanges;
ProxyData _lastSelectedProxy;
bool _lastSelectedProxyUsed = false;

View File

@ -597,7 +597,8 @@ void Call::createAndStartController(const MTPDphoneCall &call) {
_controller->SetConfig(config);
_controller->SetEncryptionKey(reinterpret_cast<char*>(_authKey.data()), (_type == Type::Outgoing));
_controller->SetCallbacks(callbacks);
if (Global::UseProxy() && Global::UseProxyForCalls()) {
if (Global::UseProxyForCalls()
&& (Global::ProxySettings() == ProxyData::Settings::Enabled)) {
const auto proxy = Global::SelectedProxy();
if (proxy.supportsCalls()) {
Assert(proxy.type == ProxyData::Type::Socks5);

View File

@ -334,6 +334,11 @@ enum DBIWorkMode {
};
struct ProxyData {
enum class Settings {
System,
Enabled,
Disabled,
};
enum class Type {
None,
Socks5,

View File

@ -662,7 +662,7 @@ struct Data {
bool TryIPv6 = (cPlatform() == dbipWindows) ? false : true;
std::vector<ProxyData> ProxiesList;
ProxyData SelectedProxy;
bool UseProxy = false;
ProxyData::Settings ProxySettings = ProxyData::Settings::System;
bool UseProxyForCalls = false;
base::Observable<void> ConnectionTypeChanged;
@ -791,7 +791,7 @@ DefineVar(Global, bool, NotificationsDemoIsShown);
DefineVar(Global, bool, TryIPv6);
DefineVar(Global, std::vector<ProxyData>, ProxiesList);
DefineVar(Global, ProxyData, SelectedProxy);
DefineVar(Global, bool, UseProxy);
DefineVar(Global, ProxyData::Settings, ProxySettings);
DefineVar(Global, bool, UseProxyForCalls);
DefineRefVar(Global, base::Observable<void>, ConnectionTypeChanged);

View File

@ -317,7 +317,7 @@ DeclareVar(bool, NotificationsDemoIsShown);
DeclareVar(bool, TryIPv6);
DeclareVar(std::vector<ProxyData>, ProxiesList);
DeclareVar(ProxyData, SelectedProxy);
DeclareVar(bool, UseProxy);
DeclareVar(ProxyData::Settings, ProxySettings);
DeclareVar(bool, UseProxyForCalls);
DeclareRefVar(base::Observable<void>, ConnectionTypeChanged);

View File

@ -283,18 +283,19 @@ bool Messenger::eventFilter(QObject *object, QEvent *e) {
void Messenger::setCurrentProxy(
const ProxyData &proxy,
bool enabled) {
ProxyData::Settings settings) {
const auto key = [&](const ProxyData &proxy) {
if (proxy.type == ProxyData::Type::Mtproto) {
return std::make_pair(proxy.host, proxy.port);
}
return std::make_pair(QString(), uint32(0));
};
const auto previousKey = key(Global::UseProxy()
? Global::SelectedProxy()
: ProxyData());
const auto previousKey = key(
(Global::ProxySettings() == ProxyData::Settings::Enabled
? Global::SelectedProxy()
: ProxyData()));
Global::SetSelectedProxy(proxy);
Global::SetUseProxy(enabled);
Global::SetProxySettings(settings);
Sandbox::refreshGlobalProxy();
if (_mtproto) {
_mtproto->restart();
@ -309,10 +310,16 @@ void Messenger::setCurrentProxy(
}
void Messenger::badMtprotoConfigurationError() {
if (Global::UseProxy() && !_badProxyDisableBox) {
if (Global::ProxySettings() == ProxyData::Settings::Enabled
&& !_badProxyDisableBox) {
const auto disableCallback = [=] {
setCurrentProxy(
Global::SelectedProxy(),
ProxyData::Settings::System);
};
_badProxyDisableBox = Ui::show(Box<InformBox>(
Lang::Hard::ProxyConfigError(),
[=] { setCurrentProxy(Global::SelectedProxy(), false); }));
disableCallback));
}
}

View File

@ -107,7 +107,9 @@ public:
MTP::DcOptions *dcOptions() {
return _dcOptions.get();
}
void setCurrentProxy(const ProxyData &proxy, bool enabled);
void setCurrentProxy(
const ProxyData &proxy,
ProxyData::Settings settings);
void badMtprotoConfigurationError();
// Set from legacy storage.

View File

@ -102,7 +102,7 @@ void ConfigLoader::enumerate() {
}
void ConfigLoader::refreshSpecialLoader() {
if (Global::UseProxy()) {
if (Global::ProxySettings() == ProxyData::Settings::Enabled) {
_specialLoader.reset();
return;
}
@ -157,7 +157,7 @@ void ConfigLoader::addSpecialEndpoint(
void ConfigLoader::sendSpecialRequest() {
terminateSpecialRequest();
if (Global::UseProxy()) {
if (Global::ProxySettings() == ProxyData::Settings::Enabled) {
_specialLoader.reset();
return;
}

View File

@ -329,7 +329,8 @@ void Instance::Private::applyDomainIps(
for (auto &proxy : Global::RefProxiesList()) {
applyToProxy(proxy);
}
if (applyToProxy(Global::RefSelectedProxy()) && Global::UseProxy()) {
if (applyToProxy(Global::RefSelectedProxy())
&& (Global::ProxySettings() == ProxyData::Settings::Enabled)) {
for (auto &session : _sessions) {
session.second->refreshOptions();
}
@ -358,7 +359,8 @@ void Instance::Private::setGoodProxyDomain(
for (auto &proxy : Global::RefProxiesList()) {
applyToProxy(proxy);
}
if (applyToProxy(Global::RefSelectedProxy()) && Global::UseProxy()) {
if (applyToProxy(Global::RefSelectedProxy())
&& (Global::ProxySettings() == ProxyData::Settings::Enabled)) {
Sandbox::refreshGlobalProxy();
}
}

View File

@ -171,9 +171,10 @@ void Session::restart() {
void Session::refreshOptions() {
const auto &proxy = Global::SelectedProxy();
const auto proxyType = Global::UseProxy()
? proxy.type
: ProxyData::Type::None;
const auto proxyType =
(Global::ProxySettings() == ProxyData::Settings::Enabled
? proxy.type
: ProxyData::Type::None);
const auto useTcp = (proxyType != ProxyData::Type::Http);
const auto useHttp = (proxyType != ProxyData::Type::Mtproto);
const auto useIPv4 = true;
@ -182,7 +183,9 @@ void Session::refreshOptions() {
_instance->systemLangCode(),
_instance->cloudLangCode(),
_instance->langPackName(),
Global::UseProxy() ? proxy : ProxyData(),
(Global::ProxySettings() == ProxyData::Settings::Enabled
? proxy
: ProxyData()),
useIPv4,
useIPv6,
useHttp,

View File

@ -43,7 +43,7 @@ void SetupConnectionType(not_null<Ui::VerticalLayout*> container) {
#ifndef TDESKTOP_DISABLE_NETWORK_PROXY
const auto connectionType = [] {
const auto transport = MTP::dctransport();
if (!Global::UseProxy()) {
if (Global::ProxySettings() != ProxyData::Settings::Enabled) {
return transport.isEmpty()
? lang(lng_connection_auto_connecting)
: lng_connection_auto(lt_transport, transport);

View File

@ -612,7 +612,8 @@ enum {
dbictHttpAuto = 1, // not used
dbictHttpProxy = 2,
dbictTcpProxy = 3,
dbictProxiesList = 4,
dbictProxiesListOld = 4,
dbictProxiesList = 5,
};
typedef QMap<PeerId, FileKey> DraftsMap;
@ -1214,7 +1215,9 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
} break;
};
Global::SetSelectedProxy(proxy ? proxy : ProxyData());
Global::SetUseProxy(proxy ? true : false);
Global::SetProxySettings(proxy
? ProxyData::Settings::Enabled
: ProxyData::Settings::System);
if (proxy) {
Global::SetProxiesList({ 1, proxy });
} else {
@ -1248,14 +1251,16 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
: ProxyData::Type::None;
return proxy;
};
if (connectionType == dbictProxiesList) {
if (connectionType == dbictProxiesListOld
|| connectionType == dbictProxiesList) {
qint32 count = 0, index = 0;
stream >> count >> index;
if (std::abs(index) > count) {
Global::SetUseProxyForCalls(true);
qint32 settings = 0, calls = 0;
if (connectionType == dbictProxiesList) {
stream >> settings >> calls;
} else if (std::abs(index) > count) {
calls = 1;
index -= (index > 0 ? count : -count);
} else {
Global::SetUseProxyForCalls(false);
}
auto list = std::vector<ProxyData>();
@ -1273,13 +1278,31 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
return false;
}
Global::SetProxiesList(list);
Global::SetUseProxy(index > 0 && index <= list.size());
index = std::abs(index);
if (connectionType == dbictProxiesListOld) {
settings = static_cast<qint32>(
(index > 0 && index <= list.size()
? ProxyData::Settings::Enabled
: ProxyData::Settings::System));
index = std::abs(index);
}
if (index > 0 && index <= list.size()) {
Global::SetSelectedProxy(list[index - 1]);
} else {
Global::SetSelectedProxy(ProxyData());
}
const auto unchecked = static_cast<ProxyData::Settings>(settings);
switch (unchecked) {
case ProxyData::Settings::Disabled:
case ProxyData::Settings::System:
case ProxyData::Settings::Enabled:
Global::SetProxySettings(unchecked);
break;
default:
Global::SetProxySettings(ProxyData::Settings::System);
break;
}
Global::SetUseProxyForCalls(calls == 1);
} else {
const auto proxy = readProxy();
if (!_checkStreamStatus(stream)) {
@ -1290,14 +1313,14 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
Global::SetSelectedProxy(proxy);
if (connectionType == dbictTcpProxy
|| connectionType == dbictHttpProxy) {
Global::SetUseProxy(true);
Global::SetProxySettings(ProxyData::Settings::Enabled);
} else {
Global::SetUseProxy(false);
Global::SetProxySettings(ProxyData::Settings::System);
}
} else {
Global::SetProxiesList({});
Global::SetSelectedProxy(ProxyData());
Global::SetUseProxy(false);
Global::SetProxySettings(ProxyData::Settings::System);
}
}
Sandbox::refreshGlobalProxy();
@ -2576,10 +2599,9 @@ void writeSettings() {
data.stream << quint32(dbiConnectionType) << qint32(dbictProxiesList);
data.stream << qint32(proxies.size());
const auto index = qint32(proxyIt - begin(proxies))
+ qint32(Global::UseProxyForCalls() ? proxies.size() : 0)
+ 1;
data.stream << (Global::UseProxy() ? index : -index);
data.stream << qint32(proxyIt - begin(proxies)) + 1;
data.stream << qint32(Global::ProxySettings());
data.stream << qint32(Global::UseProxyForCalls() ? 1 : 0);
for (const auto &proxy : proxies) {
data.stream << qint32(kProxyTypeShift + int(proxy.type));
data.stream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password;

View File

@ -345,7 +345,8 @@ void ConnectingWidget::refreshState() {
const auto state = [&]() -> State {
const auto under = isOver();
const auto mtp = MTP::dcstate();
const auto throughProxy = Global::UseProxy();
const auto throughProxy
= (Global::ProxySettings() == ProxyData::Settings::Enabled);
if (mtp == MTP::ConnectingState
|| mtp == MTP::DisconnectedState
|| (mtp < 0 && mtp > -600)) {