Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Eric Kotato 2020-05-13 00:44:45 +03:00
commit 1da7b32a3f
9 changed files with 139 additions and 41 deletions

View file

@ -22,6 +22,9 @@ bool IsApplicationActive() {
} }
bool TranslucentWindowsSupported(QPoint globalPosition) { bool TranslucentWindowsSupported(QPoint globalPosition) {
if (QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive)) {
return true;
}
if (const auto native = QGuiApplication::platformNativeInterface()) { if (const auto native = QGuiApplication::platformNativeInterface()) {
if (const auto desktop = QApplication::desktop()) { if (const auto desktop = QApplication::desktop()) {
const auto index = desktop->screenNumber(globalPosition); const auto index = desktop->screenNumber(globalPosition);

View file

@ -36,7 +36,7 @@ void IgnoreAllActivation(not_null<QWidget*> widget) {
Assert(handle != nullptr); Assert(handle != nullptr);
ShowWindow(handle, SW_HIDE); ShowWindow(handle, SW_HIDE);
const auto style = GetWindowLong(handle, GWL_EXSTYLE); const auto style = GetWindowLongPtr(handle, GWL_EXSTYLE);
SetWindowLong( SetWindowLong(
handle, handle,
GWL_EXSTYLE, GWL_EXSTYLE,

View file

@ -16,6 +16,22 @@
#include <windowsx.h> #include <windowsx.h>
// WM_POINTER support from Windows 8 onwards (WINVER >= 0x0602)
#ifndef WM_POINTERUPDATE
# define WM_NCPOINTERUPDATE 0x0241
# define WM_NCPOINTERDOWN 0x0242
# define WM_NCPOINTERUP 0x0243
# define WM_POINTERUPDATE 0x0245
# define WM_POINTERDOWN 0x0246
# define WM_POINTERUP 0x0247
# define WM_POINTERENTER 0x0249
# define WM_POINTERLEAVE 0x024A
# define WM_POINTERACTIVATE 0x024B
# define WM_POINTERCAPTURECHANGED 0x024C
# define WM_POINTERWHEEL 0x024E
# define WM_POINTERHWHEEL 0x024F
#endif // WM_POINTERUPDATE
namespace Ui { namespace Ui {
namespace Platform { namespace Platform {
namespace { namespace {
@ -197,7 +213,7 @@ void WindowShadow::init(QColor color) {
return; return;
} }
ShadowByHandle.emplace(_handles[i], this); ShadowByHandle.emplace(_handles[i], this);
SetWindowLong(_handles[i], GWL_HWNDPARENT, (LONG)_handle); SetWindowLongPtr(_handles[i], GWLP_HWNDPARENT, (LONG)_handle);
_contexts[i] = CreateCompatibleDC(_screenContext); _contexts[i] = CreateCompatibleDC(_screenContext);
if (!_contexts[i]) { if (!_contexts[i]) {

View file

@ -70,7 +70,7 @@ bool WindowHelper::NativeFilter::nativeEventFilter(
msg->message, msg->message,
msg->wParam, msg->wParam,
msg->lParam, msg->lParam,
static_cast<LRESULT*>(result)) reinterpret_cast<LRESULT*>(result))
: false; : false;
} }
@ -269,7 +269,7 @@ bool WindowHelper::handleNativeEvent(
} return false; } return false;
case WM_SHOWWINDOW: { case WM_SHOWWINDOW: {
const auto style = GetWindowLong(_handle, GWL_STYLE); const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
const auto changes = WindowShadow::Change::Resized const auto changes = WindowShadow::Change::Resized
| ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE))) | ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE)))
? WindowShadow::Change::Shown ? WindowShadow::Change::Shown
@ -375,8 +375,8 @@ void WindowHelper::updateMargins() {
GetClientRect(_handle, &r); GetClientRect(_handle, &r);
a = r; a = r;
const auto style = GetWindowLong(_handle, GWL_STYLE); const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
const auto styleEx = GetWindowLong(_handle, GWL_EXSTYLE); const auto styleEx = GetWindowLongPtr(_handle, GWL_EXSTYLE);
AdjustWindowRectEx(&a, style, false, styleEx); AdjustWindowRectEx(&a, style, false, styleEx);
auto margins = QMargins( auto margins = QMargins(
a.left - r.left, a.left - r.left,

View file

@ -211,6 +211,14 @@ QString FontTypeNames[FontTypesCount] = {
"DAOpenSansSemibold", "DAOpenSansSemibold",
"DAOpenSansSemiboldItalic", "DAOpenSansSemiboldItalic",
}; };
QString FontTypePersianFallbackFiles[FontTypesCount] = {
"DAVazirRegular",
"DAVazirRegular",
"DAVazirMediumAsBold",
"DAVazirMediumAsBold",
"DAVazirMediumAsBold",
"DAVazirMediumAsBold",
};
QString FontTypePersianFallback[FontTypesCount] = { QString FontTypePersianFallback[FontTypesCount] = {
"DAVazirRegular", "DAVazirRegular",
"DAVazirRegular", "DAVazirRegular",
@ -228,16 +236,6 @@ int32 FontTypeFlags[FontTypesCount] = {
FontSemibold, FontSemibold,
FontSemibold | FontItalic, FontSemibold | FontItalic,
}; };
#ifdef Q_OS_WIN
QString FontTypeWindowsFallback[FontTypesCount] = {
"Segoe UI",
"Segoe UI",
"Segoe UI",
"Segoe UI",
"Segoe UI",
"Segoe UI",
};
#endif // Q_OS_WIN
bool Started = false; bool Started = false;
QString Overrides[FontTypesCount]; QString Overrides[FontTypesCount];
@ -266,10 +264,6 @@ void StartFonts() {
#ifndef DESKTOP_APP_USE_PACKAGED_FONTS #ifndef DESKTOP_APP_USE_PACKAGED_FONTS
if (!UseSystemFont) { if (!UseSystemFont) {
LoadCustomFont(":/gui/fonts/DAVazirRegular.ttf", "DAVazirRegular");
LoadCustomFont(":/gui/fonts/DAVazirBold.ttf", "DAVazirBold", style::internal::FontBold);
LoadCustomFont(":/gui/fonts/DAVazirMedium.ttf", "DAVazirMedium", style::internal::FontSemibold);
bool areGood[FontTypesCount] = { false }; bool areGood[FontTypesCount] = { false };
for (auto i = 0; i != FontTypesCount; ++i) { for (auto i = 0; i != FontTypesCount; ++i) {
const auto file = FontTypeFiles[i]; const auto file = FontTypeFiles[i];
@ -278,12 +272,16 @@ void StartFonts() {
areGood[i] = LoadCustomFont(":/gui/fonts/" + file + ".ttf", name, flags); areGood[i] = LoadCustomFont(":/gui/fonts/" + file + ".ttf", name, flags);
Overrides[i] = name; Overrides[i] = name;
const auto persianFallbackFile = FontTypePersianFallbackFiles[i];
const auto persianFallback = FontTypePersianFallback[i];
LoadCustomFont(":/gui/fonts/" + persianFallbackFile + ".ttf", persianFallback, flags);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Attempt to workaround a strange font bug with Open Sans Semibold not loading. // Attempt to workaround a strange font bug with Open Sans Semibold not loading.
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details. // See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
// Crash happens on "options.maxh / _t->_st->font->height" with "division by zero". // Crash happens on "options.maxh / _t->_st->font->height" with "division by zero".
// In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold"). // In that place "_t->_st->font" is "semiboldFont" is "font(13 "Open Sans Semibold").
const auto fallback = FontTypeWindowsFallback[i]; const auto fallback = "Segoe UI";
if (!areGood[i]) { if (!areGood[i]) {
if (ValidateFont(fallback, flags)) { if (ValidateFont(fallback, flags)) {
Overrides[i] = fallback; Overrides[i] = fallback;
@ -296,10 +294,7 @@ void StartFonts() {
//QFont::insertSubstitution(name, fallback); //QFont::insertSubstitution(name, fallback);
#endif // Q_OS_WIN #endif // Q_OS_WIN
#if defined Q_OS_WIN || defined Q_OS_LINUX
const auto persianFallback = FontTypePersianFallback[i];
QFont::insertSubstitution(name, persianFallback); QFont::insertSubstitution(name, persianFallback);
#endif // Q_OS_WIN || Q_OS_LINUX
} }
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@ -399,17 +394,17 @@ FontData::FontData(int size, uint32 flags, int family, Font *other)
} }
f.setPixelSize(size); f.setPixelSize(size);
f.setBold((_flags & FontBold) || (_flags & FontSemibold));
f.setItalic(_flags & FontItalic); f.setItalic(_flags & FontItalic);
f.setUnderline(_flags & FontUnderline); f.setUnderline(_flags & FontUnderline);
f.setStrikeOut(_flags & FontStrikeOut); f.setStrikeOut(_flags & FontStrikeOut);
if ((_flags & FontBold) || (_flags & FontSemibold)) { if ((_flags & FontBold) || (_flags & FontSemibold)) {
if (CustomSemiboldIsBold) { #ifdef DESKTOP_APP_USE_PACKAGED_FONTS
f.setBold(true); f.setWeight(QFont::DemiBold);
} else { #else // DESKTOP_APP_USE_PACKAGED_FONTS
f.setStyleName("Semibold"); f.setBold(true);
} f.setStyleName("Semibold");
#endif // !DESKTOP_APP_USE_PACKAGED_FONTS
} }
if (IsRealSemibold(fontOverride)) { if (IsRealSemibold(fontOverride)) {

View file

@ -2755,7 +2755,7 @@ void String::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
_maxWidth = _minHeight = 0; _maxWidth = _minHeight = 0;
int32 lineHeight = 0; int32 lineHeight = 0;
int32 result = 0, lastNewlineStart = 0; int32 lastNewlineStart = 0;
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0; QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) { for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
auto b = i->get(); auto b = i->get();
@ -2823,6 +2823,63 @@ void String::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
} }
} }
int String::countMaxMonospaceWidth() const {
NewlineBlock *lastNewline = 0;
auto result = QFixed();
auto paragraphWidth = QFixed();
auto lastNewlineStart = 0;
auto fullMonospace = true;
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
auto b = i->get();
auto _btype = b->type();
if (_btype == TextBlockTNewline) {
lastNewlineStart = b->from();
lastNewline = static_cast<NewlineBlock*>(b);
last_rBearing = b->f_rbearing();
last_rPadding = b->f_rpadding();
if (fullMonospace) {
accumulate_max(paragraphWidth, _width);
accumulate_max(result, paragraphWidth);
paragraphWidth = 0;
} else {
fullMonospace = true;
}
_width = (b->f_width() - last_rBearing);
continue;
}
if (!(b->flags() & (TextBlockFPre | TextBlockFCode))
&& (b->type() != TextBlockTSkip)) {
fullMonospace = false;
}
auto b__f_rbearing = b->f_rbearing(); // cache
// We need to accumulate max width after each block, because
// some blocks have width less than -1 * previous right bearing.
// In that cases the _width gets _smaller_ after moving to the next block.
//
// But when we layout block and we're sure that _maxWidth is enough
// for all the blocks to fit on their line we check each block, even the
// intermediate one with a large negative right bearing.
if (fullMonospace) {
accumulate_max(paragraphWidth, _width);
}
_width += last_rBearing + (last_rPadding + b->f_width() - b__f_rbearing);
last_rBearing = b__f_rbearing;
last_rPadding = b->f_rpadding();
continue;
}
if (_width > 0 && fullMonospace) {
accumulate_max(paragraphWidth, _width);
accumulate_max(result, paragraphWidth);
}
return result.ceil().toInt();
}
void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options) { void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options) {
_st = &st; _st = &st;
clear(); clear();

View file

@ -128,12 +128,13 @@ public:
bool updateSkipBlock(int width, int height); bool updateSkipBlock(int width, int height);
bool removeSkipBlock(); bool removeSkipBlock();
int32 maxWidth() const { int maxWidth() const {
return _maxWidth.ceil().toInt(); return _maxWidth.ceil().toInt();
} }
int32 minHeight() const { int minHeight() const {
return _minHeight; return _minHeight;
} }
int countMaxMonospaceWidth() const;
void draw(Painter &p, int32 left, int32 top, int32 width, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, TextSelection selection = { 0, 0 }, bool fullWidthSelection = true) const; void draw(Painter &p, int32 left, int32 top, int32 width, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, TextSelection selection = { 0, 0 }, bool fullWidthSelection = true) const;
void drawElided(Painter &p, int32 left, int32 top, int32 width, int32 lines = 1, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, int32 removeFromEnd = 0, bool breakEverywhere = false, TextSelection selection = { 0, 0 }) const; void drawElided(Painter &p, int32 left, int32 top, int32 width, int32 lines = 1, style::align align = style::al_left, int32 yFrom = 0, int32 yTo = -1, int32 removeFromEnd = 0, bool breakEverywhere = false, TextSelection selection = { 0, 0 }) const;

View file

@ -1997,7 +1997,7 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13) const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13)
&& (_st.font->f.family() == qstr("DAOpenSansRegular")); && (_st.font->f.family() == qstr("DAOpenSansRegular"));
auto isTildeFragment = false; auto isTildeFragment = false;
const auto tildeFixedFont = _st.font->semibold(); auto tildeFixedFont = _st.font->semibold()->f;
// First tag handling (the one we inserted text to). // First tag handling (the one we inserted text to).
bool startTagFound = false; bool startTagFound = false;
@ -2047,6 +2047,11 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
break; break;
} }
if (tildeFormatting) { if (tildeFormatting) {
const auto formatFont = format.font();
if (!tildeFixedFont.styleName().isEmpty()
&& formatFont.styleName().isEmpty()) {
tildeFixedFont.setStyleName(QString());
}
isTildeFragment = (format.font() == tildeFixedFont); isTildeFragment = (format.font() == tildeFixedFont);
} }
@ -2108,7 +2113,7 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
break; break;
} }
if (breakTagOnNotLetter && !ch->isLetter()) { if (breakTagOnNotLetter && !ch->isLetterOrNumber()) {
// Remove tag name till the end if no current action is prepared. // Remove tag name till the end if no current action is prepared.
if (action.type != ActionType::Invalid) { if (action.type != ActionType::Invalid) {
break; break;
@ -2209,6 +2214,22 @@ void InputField::onDocumentContentsChange(
return; return;
} }
// In case of input method events Qt emits
// document content change signals for a whole
// text block where the even took place.
// This breaks our wysiwyg markup, so we adjust
// the parameters to match the real change.
if (_inputMethodCommit.has_value()
&& charsAdded > _inputMethodCommit->size()
&& charsRemoved > 0) {
const auto inBlockBefore = charsAdded - _inputMethodCommit->size();
if (charsRemoved >= inBlockBefore) {
charsAdded -= inBlockBefore;
charsRemoved -= inBlockBefore;
position += inBlockBefore;
}
}
const auto document = _inner->document(); const auto document = _inner->document();
// Qt bug workaround https://bugreports.qt.io/browse/QTBUG-49062 // Qt bug workaround https://bugreports.qt.io/browse/QTBUG-49062
@ -2697,6 +2718,8 @@ void InputField::keyPressEventInner(QKeyEvent *e) {
const auto oldPosition = textCursor().position(); const auto oldPosition = textCursor().position();
if (enter && ctrl) { if (enter && ctrl) {
e->setModifiers(e->modifiers() & ~Qt::ControlModifier); e->setModifiers(e->modifiers() & ~Qt::ControlModifier);
} else if (enter && shift) {
e->setModifiers(e->modifiers() & ~Qt::ShiftModifier);
} }
_inner->QTextEdit::keyPressEvent(e); _inner->QTextEdit::keyPressEvent(e);
auto cursor = textCursor(); auto cursor = textCursor();
@ -2906,8 +2929,9 @@ void InputField::inputMethodEventInner(QInputMethodEvent *e) {
_lastPreEditText = preedit; _lastPreEditText = preedit;
startPlaceholderAnimation(); startPlaceholderAnimation();
} }
const auto text = e->commitString(); _inputMethodCommit = e->commitString();
_inner->QTextEdit::inputMethodEvent(e); _inner->QTextEdit::inputMethodEvent(e);
const auto text = *base::take(_inputMethodCommit);
if (!processMarkdownReplaces(text)) { if (!processMarkdownReplaces(text)) {
processInstantReplaces(text); processInstantReplaces(text);
} }

View file

@ -464,19 +464,21 @@ private:
int _maxLength = -1; int _maxLength = -1;
int _minHeight = -1; int _minHeight = -1;
int _maxHeight = -1; int _maxHeight = -1;
bool _forcePlaceholderHidden = false;
bool _reverseMarkdownReplacement = false;
const std::unique_ptr<Inner> _inner; const std::unique_ptr<Inner> _inner;
TextWithTags _lastTextWithTags;
std::vector<MarkdownTag> _lastMarkdownTags;
QString _lastPreEditText;
Fn<bool( Fn<bool(
EditLinkSelection selection, EditLinkSelection selection,
QString text, QString text,
QString link, QString link,
EditLinkAction action)> _editLinkCallback; EditLinkAction action)> _editLinkCallback;
TextWithTags _lastTextWithTags;
std::vector<MarkdownTag> _lastMarkdownTags;
QString _lastPreEditText;
std::optional<QString> _inputMethodCommit;
bool _forcePlaceholderHidden = false;
bool _reverseMarkdownReplacement = false;
// Tags list which we should apply while setText() call or insert from mime data. // Tags list which we should apply while setText() call or insert from mime data.
TagList _insertedTags; TagList _insertedTags;