Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
1da7b32a3f
9 changed files with 139 additions and 41 deletions
|
|
@ -22,6 +22,9 @@ bool IsApplicationActive() {
|
|||
}
|
||||
|
||||
bool TranslucentWindowsSupported(QPoint globalPosition) {
|
||||
if (QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
||||
if (const auto desktop = QApplication::desktop()) {
|
||||
const auto index = desktop->screenNumber(globalPosition);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ void IgnoreAllActivation(not_null<QWidget*> widget) {
|
|||
Assert(handle != nullptr);
|
||||
|
||||
ShowWindow(handle, SW_HIDE);
|
||||
const auto style = GetWindowLong(handle, GWL_EXSTYLE);
|
||||
const auto style = GetWindowLongPtr(handle, GWL_EXSTYLE);
|
||||
SetWindowLong(
|
||||
handle,
|
||||
GWL_EXSTYLE,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,22 @@
|
|||
|
||||
#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 Platform {
|
||||
namespace {
|
||||
|
|
@ -197,7 +213,7 @@ void WindowShadow::init(QColor color) {
|
|||
return;
|
||||
}
|
||||
ShadowByHandle.emplace(_handles[i], this);
|
||||
SetWindowLong(_handles[i], GWL_HWNDPARENT, (LONG)_handle);
|
||||
SetWindowLongPtr(_handles[i], GWLP_HWNDPARENT, (LONG)_handle);
|
||||
|
||||
_contexts[i] = CreateCompatibleDC(_screenContext);
|
||||
if (!_contexts[i]) {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ bool WindowHelper::NativeFilter::nativeEventFilter(
|
|||
msg->message,
|
||||
msg->wParam,
|
||||
msg->lParam,
|
||||
static_cast<LRESULT*>(result))
|
||||
reinterpret_cast<LRESULT*>(result))
|
||||
: false;
|
||||
}
|
||||
|
||||
|
|
@ -269,7 +269,7 @@ bool WindowHelper::handleNativeEvent(
|
|||
} return false;
|
||||
|
||||
case WM_SHOWWINDOW: {
|
||||
const auto style = GetWindowLong(_handle, GWL_STYLE);
|
||||
const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
|
||||
const auto changes = WindowShadow::Change::Resized
|
||||
| ((wParam && !(style & (WS_MAXIMIZE | WS_MINIMIZE)))
|
||||
? WindowShadow::Change::Shown
|
||||
|
|
@ -375,8 +375,8 @@ void WindowHelper::updateMargins() {
|
|||
GetClientRect(_handle, &r);
|
||||
a = r;
|
||||
|
||||
const auto style = GetWindowLong(_handle, GWL_STYLE);
|
||||
const auto styleEx = GetWindowLong(_handle, GWL_EXSTYLE);
|
||||
const auto style = GetWindowLongPtr(_handle, GWL_STYLE);
|
||||
const auto styleEx = GetWindowLongPtr(_handle, GWL_EXSTYLE);
|
||||
AdjustWindowRectEx(&a, style, false, styleEx);
|
||||
auto margins = QMargins(
|
||||
a.left - r.left,
|
||||
|
|
|
|||
|
|
@ -211,6 +211,14 @@ QString FontTypeNames[FontTypesCount] = {
|
|||
"DAOpenSansSemibold",
|
||||
"DAOpenSansSemiboldItalic",
|
||||
};
|
||||
QString FontTypePersianFallbackFiles[FontTypesCount] = {
|
||||
"DAVazirRegular",
|
||||
"DAVazirRegular",
|
||||
"DAVazirMediumAsBold",
|
||||
"DAVazirMediumAsBold",
|
||||
"DAVazirMediumAsBold",
|
||||
"DAVazirMediumAsBold",
|
||||
};
|
||||
QString FontTypePersianFallback[FontTypesCount] = {
|
||||
"DAVazirRegular",
|
||||
"DAVazirRegular",
|
||||
|
|
@ -228,16 +236,6 @@ int32 FontTypeFlags[FontTypesCount] = {
|
|||
FontSemibold,
|
||||
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;
|
||||
QString Overrides[FontTypesCount];
|
||||
|
|
@ -266,10 +264,6 @@ void StartFonts() {
|
|||
|
||||
#ifndef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
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 };
|
||||
for (auto i = 0; i != FontTypesCount; ++i) {
|
||||
const auto file = FontTypeFiles[i];
|
||||
|
|
@ -278,12 +272,16 @@ void StartFonts() {
|
|||
areGood[i] = LoadCustomFont(":/gui/fonts/" + file + ".ttf", name, flags);
|
||||
Overrides[i] = name;
|
||||
|
||||
const auto persianFallbackFile = FontTypePersianFallbackFiles[i];
|
||||
const auto persianFallback = FontTypePersianFallback[i];
|
||||
LoadCustomFont(":/gui/fonts/" + persianFallbackFile + ".ttf", persianFallback, flags);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Attempt to workaround a strange font bug with Open Sans Semibold not loading.
|
||||
// See https://github.com/telegramdesktop/tdesktop/issues/3276 for details.
|
||||
// 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").
|
||||
const auto fallback = FontTypeWindowsFallback[i];
|
||||
const auto fallback = "Segoe UI";
|
||||
if (!areGood[i]) {
|
||||
if (ValidateFont(fallback, flags)) {
|
||||
Overrides[i] = fallback;
|
||||
|
|
@ -296,10 +294,7 @@ void StartFonts() {
|
|||
//QFont::insertSubstitution(name, fallback);
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
#if defined Q_OS_WIN || defined Q_OS_LINUX
|
||||
const auto persianFallback = FontTypePersianFallback[i];
|
||||
QFont::insertSubstitution(name, persianFallback);
|
||||
#endif // Q_OS_WIN || Q_OS_LINUX
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
|
@ -399,17 +394,17 @@ FontData::FontData(int size, uint32 flags, int family, Font *other)
|
|||
}
|
||||
|
||||
f.setPixelSize(size);
|
||||
f.setBold((_flags & FontBold) || (_flags & FontSemibold));
|
||||
f.setItalic(_flags & FontItalic);
|
||||
f.setUnderline(_flags & FontUnderline);
|
||||
f.setStrikeOut(_flags & FontStrikeOut);
|
||||
|
||||
if ((_flags & FontBold) || (_flags & FontSemibold)) {
|
||||
if (CustomSemiboldIsBold) {
|
||||
f.setBold(true);
|
||||
} else {
|
||||
f.setStyleName("Semibold");
|
||||
}
|
||||
#ifdef DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
f.setWeight(QFont::DemiBold);
|
||||
#else // DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
f.setBold(true);
|
||||
f.setStyleName("Semibold");
|
||||
#endif // !DESKTOP_APP_USE_PACKAGED_FONTS
|
||||
}
|
||||
|
||||
if (IsRealSemibold(fontOverride)) {
|
||||
|
|
|
|||
|
|
@ -2755,7 +2755,7 @@ void String::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
|||
|
||||
_maxWidth = _minHeight = 0;
|
||||
int32 lineHeight = 0;
|
||||
int32 result = 0, lastNewlineStart = 0;
|
||||
int32 lastNewlineStart = 0;
|
||||
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
|
||||
for (auto i = _blocks.cbegin(), e = _blocks.cend(); i != e; ++i) {
|
||||
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) {
|
||||
_st = &st;
|
||||
clear();
|
||||
|
|
|
|||
|
|
@ -128,12 +128,13 @@ public:
|
|||
bool updateSkipBlock(int width, int height);
|
||||
bool removeSkipBlock();
|
||||
|
||||
int32 maxWidth() const {
|
||||
int maxWidth() const {
|
||||
return _maxWidth.ceil().toInt();
|
||||
}
|
||||
int32 minHeight() const {
|
||||
int minHeight() const {
|
||||
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 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;
|
||||
|
|
|
|||
|
|
@ -1997,7 +1997,7 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
|
|||
const auto tildeFormatting = (_st.font->f.pixelSize() * style::DevicePixelRatio() == 13)
|
||||
&& (_st.font->f.family() == qstr("DAOpenSansRegular"));
|
||||
auto isTildeFragment = false;
|
||||
const auto tildeFixedFont = _st.font->semibold();
|
||||
auto tildeFixedFont = _st.font->semibold()->f;
|
||||
|
||||
// First tag handling (the one we inserted text to).
|
||||
bool startTagFound = false;
|
||||
|
|
@ -2047,6 +2047,11 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
|
|||
break;
|
||||
}
|
||||
if (tildeFormatting) {
|
||||
const auto formatFont = format.font();
|
||||
if (!tildeFixedFont.styleName().isEmpty()
|
||||
&& formatFont.styleName().isEmpty()) {
|
||||
tildeFixedFont.setStyleName(QString());
|
||||
}
|
||||
isTildeFragment = (format.font() == tildeFixedFont);
|
||||
}
|
||||
|
||||
|
|
@ -2108,7 +2113,7 @@ void InputField::processFormatting(int insertPosition, int insertEnd) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (breakTagOnNotLetter && !ch->isLetter()) {
|
||||
if (breakTagOnNotLetter && !ch->isLetterOrNumber()) {
|
||||
// Remove tag name till the end if no current action is prepared.
|
||||
if (action.type != ActionType::Invalid) {
|
||||
break;
|
||||
|
|
@ -2209,6 +2214,22 @@ void InputField::onDocumentContentsChange(
|
|||
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();
|
||||
|
||||
// Qt bug workaround https://bugreports.qt.io/browse/QTBUG-49062
|
||||
|
|
@ -2697,6 +2718,8 @@ void InputField::keyPressEventInner(QKeyEvent *e) {
|
|||
const auto oldPosition = textCursor().position();
|
||||
if (enter && ctrl) {
|
||||
e->setModifiers(e->modifiers() & ~Qt::ControlModifier);
|
||||
} else if (enter && shift) {
|
||||
e->setModifiers(e->modifiers() & ~Qt::ShiftModifier);
|
||||
}
|
||||
_inner->QTextEdit::keyPressEvent(e);
|
||||
auto cursor = textCursor();
|
||||
|
|
@ -2906,8 +2929,9 @@ void InputField::inputMethodEventInner(QInputMethodEvent *e) {
|
|||
_lastPreEditText = preedit;
|
||||
startPlaceholderAnimation();
|
||||
}
|
||||
const auto text = e->commitString();
|
||||
_inputMethodCommit = e->commitString();
|
||||
_inner->QTextEdit::inputMethodEvent(e);
|
||||
const auto text = *base::take(_inputMethodCommit);
|
||||
if (!processMarkdownReplaces(text)) {
|
||||
processInstantReplaces(text);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,19 +464,21 @@ private:
|
|||
int _maxLength = -1;
|
||||
int _minHeight = -1;
|
||||
int _maxHeight = -1;
|
||||
bool _forcePlaceholderHidden = false;
|
||||
bool _reverseMarkdownReplacement = false;
|
||||
|
||||
const std::unique_ptr<Inner> _inner;
|
||||
|
||||
TextWithTags _lastTextWithTags;
|
||||
std::vector<MarkdownTag> _lastMarkdownTags;
|
||||
QString _lastPreEditText;
|
||||
Fn<bool(
|
||||
EditLinkSelection selection,
|
||||
QString text,
|
||||
QString link,
|
||||
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.
|
||||
TagList _insertedTags;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue