mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-24 18:43:37 +00:00
Fix #13094 Wrong IM window after opening a new window
This commit is contained in:
parent
e29cd17cea
commit
2e4cc60eec
@ -1083,6 +1083,13 @@ struct GuiApplication::Private
|
|||||||
///
|
///
|
||||||
KeyModifier meta_fake_bit;
|
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
|
/// The result of last dispatch action
|
||||||
DispatchResult dispatch_result_;
|
DispatchResult dispatch_result_;
|
||||||
|
|
||||||
@ -2300,6 +2307,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
|
string GuiApplication::inputLanguageCode() const
|
||||||
{
|
{
|
||||||
QLocale loc = inputMethod()->locale();
|
QLocale loc = inputMethod()->locale();
|
||||||
@ -2586,6 +2629,11 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
|
|||||||
if (d->global_menubar_)
|
if (d->global_menubar_)
|
||||||
d->global_menubar_->releaseKeyboard();
|
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
|
// create new view
|
||||||
int id = view_id;
|
int id = view_id;
|
||||||
while (d->views_.find(id) != d->views_.end())
|
while (d->views_.find(id) != d->views_.end())
|
||||||
|
@ -185,6 +185,19 @@ public:
|
|||||||
/// return the status bar state string
|
/// return the status bar state string
|
||||||
docstring viewStatusMessage();
|
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
|
/// \name Methods to process FuncRequests
|
||||||
//@{
|
//@{
|
||||||
/// process the func request
|
/// process the func request
|
||||||
|
@ -290,7 +290,7 @@ void GuiWorkArea::setFullScreen(bool full_screen)
|
|||||||
{
|
{
|
||||||
d->buffer_view_->setFullScreen(full_screen);
|
d->buffer_view_->setFullScreen(full_screen);
|
||||||
|
|
||||||
queryInputItemTransform();
|
queryInputItemGeometry();
|
||||||
|
|
||||||
if (full_screen && lyxrc.full_screen_scrollbar)
|
if (full_screen && lyxrc.full_screen_scrollbar)
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
@ -706,10 +706,10 @@ void GuiWorkArea::focusInEvent(QFocusEvent * e)
|
|||||||
if ((e->reason() == Qt::PopupFocusReason || e->reason() == Qt::ActiveWindowFocusReason) &&
|
if ((e->reason() == Qt::PopupFocusReason || e->reason() == Qt::ActiveWindowFocusReason) &&
|
||||||
!(this->inDialogMode())) {
|
!(this->inDialogMode())) {
|
||||||
// Switched from most of dialogs or other apps, and not on a dialog (e.g. findreplaceadv)
|
// 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 {
|
} else {
|
||||||
// Switched from advanced search dialog or else (e.g. mouse event)
|
// Switched from advanced search dialog or else (e.g. mouse event)
|
||||||
d->item_trans_needs_reset_ = false;
|
d->item_geom_needs_reset_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
startBlinkingCaret();
|
startBlinkingCaret();
|
||||||
@ -1143,33 +1143,111 @@ void GuiWorkArea::resizeEvent(QResizeEvent * ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiWorkArea::queryInputItemTransform()
|
void GuiWorkArea::queryInputItemGeometry()
|
||||||
{
|
{
|
||||||
LYXERR(
|
LYXERR(
|
||||||
Debug::DEBUG,
|
Debug::DEBUG,
|
||||||
"item_trans_ is aquired: dx() = " << d->item_trans_.dx() <<
|
"item_rect_ is aquired: x() = " << d->item_rect_.x() <<
|
||||||
" -> " << d->im_->inputItemTransform().dx() <<
|
" -> " << d->sys_im_->inputItemRectangle().x() <<
|
||||||
", dy() = " << d->item_trans_.dy() <<
|
", y() = " << d->item_rect_.y() <<
|
||||||
" -> " << d->im_->inputItemTransform().dy()
|
" -> " << 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_) {
|
resetInputItemGeometry(false);
|
||||||
LYXERR(
|
}
|
||||||
Debug::DEBUG,
|
|
||||||
"(" << this <<
|
void GuiWorkArea::resetInputItemGeometry(bool is_new_view)
|
||||||
") item_trans_ is reset: dx() = " << im_->inputItemTransform().dx() <<
|
{
|
||||||
" -> " << item_trans_.dx() <<
|
if (d->item_geom_needs_reset_) {
|
||||||
", dy() = " << im_->inputItemTransform().dy() <<
|
if (is_new_view) {
|
||||||
" -> " << item_trans_.dy()
|
LYXERR(
|
||||||
);
|
Debug::DEBUG,
|
||||||
im_->setInputItemTransform(item_trans_);
|
"QInputMethod::inputItemRectangle is reset: x = " <<
|
||||||
item_trans_needs_reset_ = false;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,7 +1258,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
|||||||
{
|
{
|
||||||
#ifdef DEBUG_PREEDIT
|
#ifdef DEBUG_PREEDIT
|
||||||
// check the language that current input method uses
|
// 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_) {
|
if (lang != im_lang_) {
|
||||||
LYXERR0("QLocale = " << QLocale::languageToString(lang));
|
LYXERR0("QLocale = " << QLocale::languageToString(lang));
|
||||||
im_lang_ = lang;
|
im_lang_ = lang;
|
||||||
@ -1189,7 +1267,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
|||||||
|
|
||||||
// Chinese IM may want cursor position even when preedit string is empty
|
// Chinese IM may want cursor position even when preedit string is empty
|
||||||
// such a case is handled below
|
// 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;
|
return;
|
||||||
|
|
||||||
// lower margin of the preedit area to separate the candidate window
|
// lower margin of the preedit area to separate the candidate window
|
||||||
@ -1208,13 +1286,13 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
|||||||
// Chinese input methods may exit here just obtaining im_cursor_rect
|
// Chinese input methods may exit here just obtaining im_cursor_rect
|
||||||
im_cursor_rect_ =
|
im_cursor_rect_ =
|
||||||
QRectF(cur_x, cur_y - dim.height(), 1, dim.height() + preedit_lower_margin);
|
QRectF(cur_x, cur_y - dim.height(), 1, dim.height() + preedit_lower_margin);
|
||||||
im_->update(Qt::ImCursorRectangle);
|
sys_im_->update(Qt::ImCursorRectangle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset item transformation since it can go wrong after the item gets
|
// reset item transformation since it can go wrong after the item gets
|
||||||
// lost and regains focus or after a new tab (dis)appears etc.
|
// 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)
|
// FIXME: shall we use real_current_font here? (see #10478)
|
||||||
FontInfo const font = buffer_view_->cursor().getFont().fontInfo();
|
FontInfo const font = buffer_view_->cursor().getFont().fontInfo();
|
||||||
@ -1361,7 +1439,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
|
|||||||
}
|
}
|
||||||
// Urge platform input method to make inputMethodQuery to check the values
|
// Urge platform input method to make inputMethodQuery to check the values
|
||||||
// set above
|
// set above
|
||||||
im_->update(Qt::ImQueryInput);
|
sys_im_->update(Qt::ImQueryInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1912,9 +1990,9 @@ GuiWorkArea * TabWorkArea::addWorkArea(Buffer & buffer, GuiView & view)
|
|||||||
updateTabTexts();
|
updateTabTexts();
|
||||||
|
|
||||||
// obtain new input item coordinates in the new and old work areas
|
// obtain new input item coordinates in the new and old work areas
|
||||||
wa->queryInputItemTransform();
|
wa->queryInputItemGeometry();
|
||||||
if (currentWorkArea())
|
if (currentWorkArea())
|
||||||
currentWorkArea()->queryInputItemTransform();
|
currentWorkArea()->queryInputItemGeometry();
|
||||||
|
|
||||||
return wa;
|
return wa;
|
||||||
}
|
}
|
||||||
@ -1940,7 +2018,7 @@ bool TabWorkArea::removeWorkArea(GuiWorkArea * work_area)
|
|||||||
else
|
else
|
||||||
// Show tabbar only if there's more than one tab.
|
// Show tabbar only if there's more than one tab.
|
||||||
showBar(count() > 1);
|
showBar(count() > 1);
|
||||||
currentWorkArea()->queryInputItemTransform();
|
currentWorkArea()->queryInputItemGeometry();
|
||||||
} else
|
} else
|
||||||
lastWorkAreaRemoved();
|
lastWorkAreaRemoved();
|
||||||
|
|
||||||
|
@ -67,8 +67,14 @@ public:
|
|||||||
|
|
||||||
/// return true if the key is part of a shortcut
|
/// return true if the key is part of a shortcut
|
||||||
bool queryKeySym(KeySymbol const & key, KeyModifier mod) const;
|
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;
|
bool inDialogMode() const;
|
||||||
void setDialogMode(bool mode);
|
void setDialogMode(bool mode);
|
||||||
|
@ -140,7 +140,7 @@ struct GuiWorkArea::Private
|
|||||||
bool need_resize_ = false;
|
bool need_resize_ = false;
|
||||||
|
|
||||||
/// provides access to the platform input method
|
/// provides access to the platform input method
|
||||||
QInputMethod * im_ = QGuiApplication::inputMethod();
|
QInputMethod * sys_im_ = QGuiApplication::inputMethod();
|
||||||
/// the current preedit text of the input method
|
/// the current preedit text of the input method
|
||||||
docstring preedit_string_;
|
docstring preedit_string_;
|
||||||
/// Number of lines used by preedit text
|
/// Number of lines used by preedit text
|
||||||
@ -149,8 +149,12 @@ struct GuiWorkArea::Private
|
|||||||
QList<QInputMethodEvent::Attribute> preedit_attr_;
|
QList<QInputMethodEvent::Attribute> preedit_attr_;
|
||||||
QRectF im_cursor_rect_;
|
QRectF im_cursor_rect_;
|
||||||
QRectF im_anchor_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_;
|
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
|
/// for debug
|
||||||
QLocale::Language im_lang_;
|
QLocale::Language im_lang_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user