Skip to content

Commit

Permalink
Timeline: hand back the focus to the input line ASAP
Browse files Browse the repository at this point in the history
There is no doubt that the most clicked widget is the timeline. We
click it to open pictures, to bring the window forward, to select
text, etc. Unfortunately, these actions ended up with unfocused
input line which was my primary reason to go ape on Quaternion.

This patch introduces a strict focus policy on the timeline which
means the timeline won't keep the focus for long, it will hand back
to the input line when possible, when pressed mouse buttons are
released.

At the same time we had to implement our own TextEdit text
selection mechanism because the original didn't pass through
required mouse events. Added bonus that the selected text will be
unselected when new selection starts.
  • Loading branch information
rpallai committed Jun 30, 2019
1 parent f847494 commit ab8ad92
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 10 deletions.
18 changes: 18 additions & 0 deletions client/chatroomwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ ChatRoomWidget::ChatRoomWidget(QWidget* parent)
m_chatEdit->setAcceptRichText(false);
m_chatEdit->setMaximumHeight(maximumChatEditHeight());
connect( m_chatEdit, &KChatEdit::returnPressed, this, &ChatRoomWidget::sendInput );
connect(m_chatEdit, &KChatEdit::copyRequested, this, [=] {
QApplication::clipboard()->setText(
m_chatEdit->textCursor().hasSelection() ? m_chatEdit->textCursor().selectedText() : selectedText
);
});
connect(m_chatEdit, &ChatEdit::proposedCompletion, this,
[=](const QStringList& matches, int pos)
{
Expand Down Expand Up @@ -725,6 +730,14 @@ void ChatRoomWidget::showMenu(int index, const QString& hoveredLink,
menu.exec(QCursor::pos());
}

void ChatRoomWidget::setGlobalSelectionBuffer(QString text)
{
if (QApplication::clipboard()->supportsSelection())
QApplication::clipboard()->setText(text, QClipboard::Selection);

selectedText = text;
}

void ChatRoomWidget::reStartShownTimer()
{
if (!readMarkerOnScreen || indicesOnScreen.empty() ||
Expand Down Expand Up @@ -812,3 +825,8 @@ void ChatRoomWidget::textDrop(const QString& text)
{
m_chatEdit->setText(text);
}

Qt::KeyboardModifiers ChatRoomWidget::getModifierKeys()
{
return QGuiApplication::keyboardModifiers();
}
3 changes: 3 additions & 0 deletions client/chatroomwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class ChatRoomWidget: public QWidget
void showMenu(int index, const QString& hoveredLink, bool showingDetails);
void fileDrop(const QString& url);
void textDrop(const QString& text);
void setGlobalSelectionBuffer(QString text);
Qt::KeyboardModifiers getModifierKeys();

private slots:
void sendInput();
Expand Down Expand Up @@ -110,6 +112,7 @@ class ChatRoomWidget: public QWidget
bool readMarkerOnScreen;
QMap<QuaternionRoom*, QVector<QTextDocument*>> roomHistories;
QString attachedFileName;
QString selectedText;

void reStartShownTimer();
QString doSendInput();
Expand Down
6 changes: 6 additions & 0 deletions client/kchatedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ void KChatEdit::keyPressEvent(QKeyEvent *event)
d->forwardHistory();
}
break;
case Qt::Key_C:
if (event->modifiers() & Qt::ControlModifier) {
emit copyRequested();
return;
}
break;
default:
break;
}
Expand Down
5 changes: 5 additions & 0 deletions client/kchatedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ class KChatEdit : public QTextEdit
*/
void returnPressed();

/**
* Emitted when the user presses Ctrl+C.
*/
void copyRequested();

protected:
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;

Expand Down
2 changes: 1 addition & 1 deletion client/qml/ActiveLabel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Label {

font.italic: true
textFormat: Text.PlainText
MouseArea
TimelineMouseArea
{
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
Expand Down
4 changes: 2 additions & 2 deletions client/qml/FileContent.qml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Attachment {
textFormat: TextEdit.PlainText
wrapMode: Text.Wrap;

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
Expand All @@ -37,7 +37,7 @@ Attachment {
? room.fileSource(eventId) : "")
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
cursorShape: Qt.IBeamCursor
Expand Down
4 changes: 2 additions & 2 deletions client/qml/ImageContent.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Attachment {
// easing.type: Easing.OutQuad
// }}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
hoverEnabled: true
Expand All @@ -36,7 +36,7 @@ Attachment {
onClicked: openExternally()
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
cursorShape: Qt.PointingHandCursor
Expand Down
9 changes: 9 additions & 0 deletions client/qml/Timeline.qml
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ Rectangle {
}
}

// This covers the area above a short chatView.
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onReleased: controller.focusInput()
}

ListView {
id: chatView

Expand Down Expand Up @@ -234,6 +241,8 @@ Rectangle {
contentHeight > 0 && count > 0 ? count / contentHeight : 0.03
// 0.03 is just an arbitrary reasonable number

property var textEditWithSelection

function ensurePreviousContent() {
if (noNeedMoreContent)
return
Expand Down
22 changes: 17 additions & 5 deletions client/qml/TimelineItem.qml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Item {
}
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}
}
Loader {
Expand All @@ -145,6 +146,7 @@ Item {

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}
}

Expand All @@ -155,6 +157,7 @@ Item {

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons
}

// There are several layout styles (av - author avatar,
Expand Down Expand Up @@ -203,7 +206,7 @@ Item {

text: (actionEvent ? "* " : "") + authorName
}
MouseArea {
TimelineMouseArea {
anchors.left: authorAvatar.left
anchors.right: authorLabel.right
anchors.top: authorLabel.top
Expand Down Expand Up @@ -328,8 +331,11 @@ Item {
else
Qt.openUrlExternally(link)
}

TimelineTextEditSelector {}
}
MouseArea {

TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.MiddleButton

Expand All @@ -340,14 +346,14 @@ Item {
}
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: controller.showMenu(index,
textFieldImpl.hoveredLink, showingDetails)
}

MouseArea {
TimelineMouseArea {
anchors.fill: parent
cursorShape: textFieldImpl.hoveredLink
? Qt.PointingHandCursor : Qt.IBeamCursor
Expand Down Expand Up @@ -492,6 +498,8 @@ Item {
anchors.left: parent.left
anchors.leftMargin: 3
z: 1

TimelineTextEditSelector {}
}
TextEdit {
text: "<a href=\"" + evtLink + "\">"+ eventId
Expand All @@ -507,7 +515,9 @@ Item {

onLinkActivated: Qt.openUrlExternally(link)

MouseArea {
TimelineTextEditSelector {}

TimelineMouseArea {
anchors.fill: parent
cursorShape: parent.hoveredLink ?
Qt.PointingHandCursor :
Expand Down Expand Up @@ -536,6 +546,8 @@ Item {

width: parent.width
anchors.top: detailsHeader.bottom

TimelineTextEditSelector {}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions client/qml/TimelineMouseArea.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import QtQuick 2.2

MouseArea {
onWheel: chatView.onWheel(wheel)
onReleased: controller.focusInput()
}
50 changes: 50 additions & 0 deletions client/qml/TimelineTextEditSelector.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import QtQuick 2.2

/*
* Unfortunately, TextEdit captures LeftButton events for text selection in a way which
* is not compatible with our focus-cancelling mechanism, so we took over the task here.
*/
MouseArea {
property var textEdit: parent
property var selectionMode: TextEdit.SelectCharacters

anchors.fill: parent
acceptedButtons: Qt.LeftButton

onPressed: {
var x = mouse.x
var y = mouse.y
if (textEdit.flickableItem) {
x += textEdit.flickableItem.contentX
y += textEdit.flickableItem.contentY
}
var hasSelection = textEdit.selectionEnd > textEdit.selectionStart
if (hasSelection && controller.getModifierKeys() & Qt.ShiftModifier) {
textEdit.moveCursorSelection(textEdit.positionAt(x, y), selectionMode)
} else {
textEdit.cursorPosition = textEdit.positionAt(x, y)
if (chatView.textEditWithSelection)
chatView.textEditWithSelection.deselect()
}
}
onDoubleClicked: {
selectionMode = TextEdit.SelectWords
textEdit.selectWord()
}
onReleased: {
selectionMode = TextEdit.SelectCharacters
controller.setGlobalSelectionBuffer(textEdit.selectedText)
chatView.textEditWithSelection = textEdit

controller.focusInput()
}
onPositionChanged: {
var x = mouse.x
var y = mouse.y
if (textEdit.flickableItem) {
x += textEdit.flickableItem.contentX
y += textEdit.flickableItem.contentY
}
textEdit.moveCursorSelection(textEdit.positionAt(x, y), selectionMode)
}
}
1 change: 1 addition & 0 deletions client/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
<file>qml/TimelineItem.qml</file>
<file>qml/ActiveLabel.qml</file>
<file>qml/TimelineMouseArea.qml</file>
<file>qml/TimelineTextEditSelector.qml</file>
</qresource>
</RCC>

0 comments on commit ab8ad92

Please sign in to comment.