mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Fix IM window position for a new window (#13094)
This commit is contained in:
parent
475d8e6433
commit
a086804eb4
@ -1083,6 +1083,13 @@ struct GuiApplication::Private
|
||||
///
|
||||
KeyModifier meta_fake_bit;
|
||||
|
||||
/// input method uses this to preserve initial input item transform
|
||||
bool first_work_area = true;
|
||||
/// geometry of the input item of the first working area
|
||||
QRectF item_rect_base_;
|
||||
/// input item transformation of the first working area
|
||||
QTransform item_trans_base_;
|
||||
|
||||
/// The result of last dispatch action
|
||||
DispatchResult dispatch_result_;
|
||||
|
||||
@ -2301,6 +2308,42 @@ docstring GuiApplication::viewStatusMessage()
|
||||
}
|
||||
|
||||
|
||||
bool GuiApplication::isFirstWorkArea() const
|
||||
{
|
||||
return d->first_work_area;
|
||||
}
|
||||
|
||||
|
||||
void GuiApplication::firstWorkAreaDone()
|
||||
{
|
||||
d->first_work_area = false;
|
||||
}
|
||||
|
||||
|
||||
QRectF GuiApplication::baseInputItemRectangle()
|
||||
{
|
||||
return d->item_rect_base_;
|
||||
}
|
||||
|
||||
|
||||
void GuiApplication::setBaseInputItemRectangle(QRectF rect)
|
||||
{
|
||||
d->item_rect_base_ = rect;
|
||||
}
|
||||
|
||||
|
||||
QTransform GuiApplication::baseInputItemTransform()
|
||||
{
|
||||
return d->item_trans_base_;
|
||||
}
|
||||
|
||||
|
||||
void GuiApplication::setBaseInputItemTransform(QTransform trans)
|
||||
{
|
||||
d->item_trans_base_ = trans;
|
||||
}
|
||||
|
||||
|
||||
string GuiApplication::inputLanguageCode() const
|
||||
{
|
||||
QLocale loc = inputMethod()->locale();
|
||||
@ -2586,6 +2629,11 @@ void GuiApplication::createView(bool autoShow, int view_id)
|
||||
if (d->global_menubar_)
|
||||
d->global_menubar_->releaseKeyboard();
|
||||
|
||||
// need to reset system input method coords with the preserved one
|
||||
// when the new view is the second one or later
|
||||
if (d->views_.size() > 0)
|
||||
current_view_->currentWorkArea()->resetInputItemGeometry(true);
|
||||
|
||||
// create new view
|
||||
int id = view_id;
|
||||
while (d->views_.find(id) != d->views_.end())
|
||||
|
@ -185,6 +185,19 @@ public:
|
||||
/// return the status bar state string
|
||||
docstring viewStatusMessage();
|
||||
|
||||
/// if current work area is the first one in the lyx application
|
||||
bool isFirstWorkArea() const;
|
||||
/// mark first work area is already set up
|
||||
void firstWorkAreaDone();
|
||||
/// input item rectangle of the base view
|
||||
QRectF baseInputItemRectangle();
|
||||
/// set input item rectangle of the base view
|
||||
void setBaseInputItemRectangle(QRectF rect);
|
||||
/// input item transform of the base view
|
||||
QTransform baseInputItemTransform();
|
||||
/// set input item transform of the base view
|
||||
void setBaseInputItemTransform(QTransform trans);
|
||||
|
||||
/// \name Methods to process FuncRequests
|
||||
//@{
|
||||
/// process the func request
|
||||
|
@ -286,7 +286,7 @@ void GuiWorkArea::setFullScreen(bool full_screen)
|
||||
{
|
||||
d->buffer_view_->setFullScreen(full_screen);
|
||||
|
||||
queryInputItemTransform();
|
||||
queryInputItemGeometry();
|
||||
|
||||
if (full_screen && lyxrc.full_screen_scrollbar)
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@ -705,10 +705,10 @@ void GuiWorkArea::focusInEvent(QFocusEvent * e)
|
||||
if ((e->reason() == Qt::PopupFocusReason || e->reason() == Qt::ActiveWindowFocusReason) &&
|
||||
!(this->inDialogMode())) {
|
||||
// Switched from most of dialogs or other apps, and not on a dialog (e.g. findreplaceadv)
|
||||
d->item_trans_needs_reset_ = true;
|
||||
d->item_geom_needs_reset_ = true;
|
||||
} else {
|
||||
// Switched from advanced search dialog or else (e.g. mouse event)
|
||||
d->item_trans_needs_reset_ = false;
|
||||
d->item_geom_needs_reset_ = false;
|
||||
}
|
||||
|
||||
startBlinkingCaret();
|
||||
@ -1142,33 +1142,111 @@ void GuiWorkArea::resizeEvent(QResizeEvent * ev)
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::queryInputItemTransform()
|
||||
void GuiWorkArea::queryInputItemGeometry()
|
||||
{
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"item_trans_ is aquired: dx() = " << d->item_trans_.dx() <<
|
||||
" -> " << d->im_->inputItemTransform().dx() <<
|
||||
", dy() = " << d->item_trans_.dy() <<
|
||||
" -> " << d->im_->inputItemTransform().dy()
|
||||
);
|
||||
Debug::DEBUG,
|
||||
"item_rect_ is aquired: x() = " << d->item_rect_.x() <<
|
||||
" -> " << d->sys_im_->inputItemRectangle().x() <<
|
||||
", y() = " << d->item_rect_.y() <<
|
||||
" -> " << d->sys_im_->inputItemRectangle().y() <<
|
||||
", width() = " << d->item_rect_.width() <<
|
||||
" -> " << d->sys_im_->inputItemRectangle().width() <<
|
||||
", height() = " << d->item_rect_.height() <<
|
||||
" -> " << d->sys_im_->inputItemRectangle().height()
|
||||
);
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"item_trans_ is aquired: dx() = " << d->item_trans_.dx() <<
|
||||
" -> " << d->sys_im_->inputItemTransform().dx() <<
|
||||
", dy() = " << d->item_trans_.dy() <<
|
||||
" -> " << d->sys_im_->inputItemTransform().dy()
|
||||
);
|
||||
|
||||
d->item_trans_ = d->im_->inputItemTransform();
|
||||
d->item_rect_ = d->sys_im_->inputItemRectangle();
|
||||
d->item_trans_ = d->sys_im_->inputItemTransform();
|
||||
|
||||
// save coordinates of the base working area for later use necessary to
|
||||
// creat new GuiViews
|
||||
if (guiApp->isFirstWorkArea()) {
|
||||
guiApp->setBaseInputItemRectangle(d->item_rect_);
|
||||
guiApp->setBaseInputItemTransform(d->item_trans_);
|
||||
guiApp->firstWorkAreaDone();
|
||||
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"base inputItemRectangle x = " <<
|
||||
guiApp->baseInputItemRectangle().x() <<
|
||||
", y = " << guiApp->baseInputItemRectangle().y() <<
|
||||
", width = " << guiApp->baseInputItemRectangle().width() <<
|
||||
", height = " << guiApp->baseInputItemRectangle().height()
|
||||
);
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"base inputItemTransform dx = " <<
|
||||
guiApp->baseInputItemTransform().dx() <<
|
||||
", dy = " << guiApp->baseInputItemTransform().dy()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GuiWorkArea::Private::resetInputItemTransform()
|
||||
void GuiWorkArea::resetInputItemGeometry()
|
||||
{
|
||||
if (item_trans_needs_reset_) {
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"(" << this <<
|
||||
") item_trans_ is reset: dx() = " << im_->inputItemTransform().dx() <<
|
||||
" -> " << item_trans_.dx() <<
|
||||
", dy() = " << im_->inputItemTransform().dy() <<
|
||||
" -> " << item_trans_.dy()
|
||||
);
|
||||
im_->setInputItemTransform(item_trans_);
|
||||
item_trans_needs_reset_ = false;
|
||||
resetInputItemGeometry(false);
|
||||
}
|
||||
|
||||
void GuiWorkArea::resetInputItemGeometry(bool is_new_view)
|
||||
{
|
||||
if (d->item_geom_needs_reset_) {
|
||||
if (is_new_view) {
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"QInputMethod::inputItemRectangle is reset: x = " <<
|
||||
d->sys_im_->inputItemRectangle().x() <<
|
||||
" -> " << guiApp->baseInputItemRectangle().x() <<
|
||||
", y = " << d->sys_im_->inputItemRectangle().y() <<
|
||||
" -> " << guiApp->baseInputItemRectangle().y() <<
|
||||
", width = " << d->sys_im_->inputItemRectangle().width() <<
|
||||
" -> " << guiApp->baseInputItemRectangle().width() <<
|
||||
", height = " << d->sys_im_->inputItemRectangle().height() <<
|
||||
" -> " << guiApp->baseInputItemRectangle().height()
|
||||
);
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"QInputMethod::inputItemTransform is reset: dx = " <<
|
||||
d->sys_im_->inputItemTransform().dx() <<
|
||||
" -> " << guiApp->baseInputItemTransform().dx() <<
|
||||
", dy = " << d->sys_im_->inputItemTransform().dy() <<
|
||||
" -> " << guiApp->baseInputItemTransform().dy()
|
||||
);
|
||||
d->sys_im_->setInputItemRectangle(guiApp->baseInputItemRectangle());
|
||||
d->sys_im_->setInputItemTransform(guiApp->baseInputItemTransform());
|
||||
} else {
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"QInputMethod::inputItemRectangle is reset: x = " <<
|
||||
d->sys_im_->inputItemRectangle().x() <<
|
||||
" -> " << d->item_rect_.x() <<
|
||||
", y = " << d->sys_im_->inputItemRectangle().y() <<
|
||||
" -> " << d->item_rect_.y() <<
|
||||
", width = " << d->sys_im_->inputItemRectangle().width() <<
|
||||
" -> " << d->item_rect_.width() <<
|
||||
", height = " << d->sys_im_->inputItemRectangle().height() <<
|
||||
" -> " << d->item_rect_.height()
|
||||
);
|
||||
LYXERR(
|
||||
Debug::DEBUG,
|
||||
"QInputMethod::inputItemTransform is reset: dx = " <<
|
||||
d->sys_im_->inputItemTransform().dx() <<
|
||||
" -> " << d->item_trans_.dx() <<
|
||||
", dy = " << d->sys_im_->inputItemTransform().dy() <<
|
||||
" -> " << d->item_trans_.dy()
|
||||
);
|
||||
d->sys_im_->setInputItemRectangle(d->item_rect_);
|
||||
d->sys_im_->setInputItemTransform(d->item_trans_);
|
||||
}
|
||||
d->item_geom_needs_reset_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1179,7 +1257,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
||||
{
|
||||
#ifdef DEBUG_PREEDIT
|
||||
// check the language that current input method uses
|
||||
QLocale::Language lang = im_->locale().language();
|
||||
QLocale::Language lang = sys_im_->locale().language();
|
||||
if (lang != im_lang_) {
|
||||
LYXERR0("QLocale = " << QLocale::languageToString(lang));
|
||||
im_lang_ = lang;
|
||||
@ -1188,7 +1266,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
||||
|
||||
// Chinese IM may want cursor position even when preedit string is empty
|
||||
// such a case is handled below
|
||||
if (preedit_string_.empty() && im_->locale().language() != QLocale::Chinese)
|
||||
if (preedit_string_.empty() && sys_im_->locale().language() != QLocale::Chinese)
|
||||
return;
|
||||
|
||||
// lower margin of the preedit area to separate the candidate window
|
||||
@ -1207,13 +1285,13 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
||||
// Chinese input methods may exit here just obtaining im_cursor_rect
|
||||
im_cursor_rect_ =
|
||||
QRectF(cur_x, cur_y - dim.height(), 1, dim.height() + preedit_lower_margin);
|
||||
im_->update(Qt::ImCursorRectangle);
|
||||
sys_im_->update(Qt::ImCursorRectangle);
|
||||
return;
|
||||
}
|
||||
|
||||
// reset item transformation since it can go wrong after the item gets
|
||||
// lost and regains focus or after a new tab (dis)appears etc.
|
||||
resetInputItemTransform();
|
||||
p->resetInputItemGeometry();
|
||||
|
||||
// FIXME: shall we use real_current_font here? (see #10478)
|
||||
FontInfo const font = buffer_view_->cursor().getFont().fontInfo();
|
||||
@ -1360,7 +1438,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
||||
}
|
||||
// Urge platform input method to make inputMethodQuery to check the values
|
||||
// set above
|
||||
im_->update(Qt::ImQueryInput);
|
||||
sys_im_->update(Qt::ImQueryInput);
|
||||
}
|
||||
|
||||
|
||||
@ -1910,9 +1988,9 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view)
|
||||
updateTabTexts();
|
||||
|
||||
// obtain new input item coordinates in the new and old work areas
|
||||
wa->queryInputItemTransform();
|
||||
wa->queryInputItemGeometry();
|
||||
if (currentWorkArea())
|
||||
currentWorkArea()->queryInputItemTransform();
|
||||
currentWorkArea()->queryInputItemGeometry();
|
||||
|
||||
view.setBusy(false);
|
||||
|
||||
@ -1940,7 +2018,7 @@ bool TabWorkArea::removeWorkArea(GuiWorkArea * work_area)
|
||||
else
|
||||
// Show tabbar only if there's more than one tab.
|
||||
showBar(count() > 1);
|
||||
currentWorkArea()->queryInputItemTransform();
|
||||
currentWorkArea()->queryInputItemGeometry();
|
||||
} else
|
||||
lastWorkAreaRemoved();
|
||||
|
||||
|
@ -69,8 +69,14 @@ public:
|
||||
|
||||
/// return true if the key is part of a shortcut
|
||||
bool queryKeySym(KeySymbol const & key, KeyModifier mod) const;
|
||||
/// Ask relative position of input item coordinates against the main coordinates
|
||||
void queryInputItemTransform();
|
||||
|
||||
/// Ask relative position of the input item coordinates against the main
|
||||
/// coordinates to the system input method
|
||||
void queryInputItemGeometry();
|
||||
/// Restore coordinate transformation information
|
||||
void resetInputItemGeometry();
|
||||
/// Restore coordinate transformation information
|
||||
void resetInputItemGeometry(bool is_new_view);
|
||||
|
||||
bool inDialogMode() const;
|
||||
void setDialogMode(bool mode);
|
||||
|
@ -137,7 +137,7 @@ struct GuiWorkArea::Private
|
||||
bool need_resize_ = false;
|
||||
|
||||
/// provides access to the platform input method
|
||||
QInputMethod * im_ = QGuiApplication::inputMethod();
|
||||
QInputMethod * sys_im_ = QGuiApplication::inputMethod();
|
||||
/// the current preedit text of the input method
|
||||
docstring preedit_string_;
|
||||
/// Number of lines used by preedit text
|
||||
@ -146,8 +146,12 @@ struct GuiWorkArea::Private
|
||||
QList<QInputMethodEvent::Attribute> preedit_attr_;
|
||||
QRectF im_cursor_rect_;
|
||||
QRectF im_anchor_rect_;
|
||||
/// geometry of the input item
|
||||
QRectF item_rect_;
|
||||
/// transformation from input item coordinates to the working area
|
||||
QTransform item_trans_;
|
||||
bool item_trans_needs_reset_ = false;
|
||||
/// whether item_rect_ and item_trans need to be reset
|
||||
bool item_geom_needs_reset_ = false;
|
||||
/// for debug
|
||||
QLocale::Language im_lang_ = QLocale::AnyLanguage;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user