From 846ac853ce9c520e2dae0ff9ccce6ff8258a2693 Mon Sep 17 00:00:00 2001 From: Wiktor Date: Sun, 11 Jun 2017 11:14:17 +0200 Subject: [PATCH] Changed URL input locking to use BMessageRunner. In the current state, opening a link in a new tab will cause URL input to become empty. This fixes the issue by changing the way locking works and implementing a lock timeout. The text passed to SetText() will be instead stored as previous text, so if the user presses ESC after editing the URL, URL input will update to the latest sent text (i. e. current URL). Also fixed two lines the style checker was complaining about. Fixes #13548. Signed-off-by: Adrien Destugues --- src/apps/webpositive/BrowserWindow.cpp | 12 +++-- src/apps/webpositive/URLInputGroup.cpp | 63 ++++++++++++++++++++++++-- src/apps/webpositive/URLInputGroup.h | 11 +++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 49eb6f6295..e899593125 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -736,6 +736,12 @@ BrowserWindow::DispatchMessage(BMessage* message, BHandler* target) _InvokeButtonVisibly(fURLInputGroup->GoButton()); return; } + // Lock the URL text control to prevent changes while user is + // typing and set a timer to unlock it after a set period + // of time. + else { + fURLInputGroup->LockURLInput(); + } } else if (target == fFindTextControl->TextView()) { // Handle B_RETURN when the find text control has focus. if (bytes[0] == B_RETURN) { @@ -844,8 +850,8 @@ BrowserWindow::MessageReceived(BMessage* message) entry_ref ref; BString name; - if (message->FindRef("directory", &ref) == B_OK && - message->FindString("name", &name) == B_OK) { + if (message->FindRef("directory", &ref) == B_OK + && message->FindString("name", &name) == B_OK) { BDirectory dir(&ref); BFile output(&dir, name, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); @@ -2448,7 +2454,7 @@ BrowserWindow::_EncodeURIComponent(const BString& search) void BrowserWindow::_VisitURL(const BString& url) { - //fURLInputGroup->TextView()->SetText(url); + // fURLInputGroup->TextView()->SetText(url); CurrentWebView()->LoadURL(url.String()); } diff --git a/src/apps/webpositive/URLInputGroup.cpp b/src/apps/webpositive/URLInputGroup.cpp index 45c083fd68..010637814a 100644 --- a/src/apps/webpositive/URLInputGroup.cpp +++ b/src/apps/webpositive/URLInputGroup.cpp @@ -151,6 +151,7 @@ public: virtual void MouseDown(BPoint where); virtual void KeyDown(const char* bytes, int32 numBytes); virtual void MakeFocus(bool focused = true); + virtual void SetPreviousText(const char* text); virtual BSize MinSize(); virtual BSize MaxSize(); @@ -302,6 +303,11 @@ URLInputGroup::URLTextView::KeyDown(const char* bytes, int32 numBytes) void URLInputGroup::URLTextView::MakeFocus(bool focus) { + // Unlock the URL input ahead of time if focus was lost. + if (!focus) { + fURLInputGroup->LockURLInput(false); + } + if (focus == IsFocus()) return; @@ -316,6 +322,13 @@ URLInputGroup::URLTextView::MakeFocus(bool focus) } +void +URLInputGroup::URLTextView::SetPreviousText(const char* text) +{ + fPreviousText = text; +} + + BSize URLInputGroup::URLTextView::MinSize() { @@ -583,7 +596,9 @@ private: URLInputGroup::URLInputGroup(BMessage* goMessage) : BGroupView(B_HORIZONTAL, 0.0), - fWindowActive(false) + fURLLockTimeout(NULL), + fWindowActive(false), + fURLLocked(false) { GroupLayout()->SetInsets(2, 2, 2, 2); @@ -608,11 +623,13 @@ URLInputGroup::URLInputGroup(BMessage* goMessage) SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_VERTICAL_CENTER)); + } URLInputGroup::~URLInputGroup() { + delete fURLLockTimeout; } @@ -666,9 +683,14 @@ URLInputGroup::TextView() const void URLInputGroup::SetText(const char* text) { - // Ignore setting the text, if the user is currently editing the URL. - if (fWindowActive && fTextView->IsFocus()) + // Ignore setting the text, if the user edited the URL in the last + // couple of seconds. Instead set the previous text in the text view, + // so if the user presses ESC the input will update to show the new + // text. + if (fURLLocked) { + fTextView->SetPreviousText(text); return; + } if (!text || !Text() || strcmp(Text(), text) != 0) { fTextView->SetUpdateAutoCompleterChoices(false); @@ -698,3 +720,38 @@ URLInputGroup::SetPageIcon(const BBitmap* icon) fIconView->SetIcon(icon); } + +void +URLInputGroup::LockURLInput(bool lock) +{ + fURLLocked = lock; + if (lock) { + if (fURLLockTimeout == NULL) { + fURLLockTimeout = new BMessageRunner(this, + new BMessage(MSG_LOCK_TIMEOUT), LOCK_TIMEOUT, 1); + } else { + fURLLockTimeout->SetInterval(LOCK_TIMEOUT); + } + } +} + + +void +URLInputGroup::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_LOCK_TIMEOUT: + { + delete fURLLockTimeout; + fURLLockTimeout = NULL; + LockURLInput(false); + break; + } + default: + { + BGroupView(message); + break; + } + } +} + diff --git a/src/apps/webpositive/URLInputGroup.h b/src/apps/webpositive/URLInputGroup.h index d71f713ca7..2e5bd72414 100644 --- a/src/apps/webpositive/URLInputGroup.h +++ b/src/apps/webpositive/URLInputGroup.h @@ -6,12 +6,18 @@ #define URL_INPUT_GROUP_H #include +#include class BButton; class BTextView; class URLInputGroup : public BGroupView { +private: + static const uint32 MSG_LOCK_TIMEOUT = 'loti'; + static const bigtime_t LOCK_TIMEOUT = 1000000; + // Lock will timeout in one second + public: URLInputGroup(BMessage* goMessage); virtual ~URLInputGroup(); @@ -29,14 +35,19 @@ public: void SetPageIcon(const BBitmap* icon); + virtual void LockURLInput(bool lock = true); + virtual void MessageReceived(BMessage* message); + private: class PageIconView; class URLTextView; + BMessageRunner* fURLLockTimeout; PageIconView* fIconView; URLTextView* fTextView; BButton* fGoButton; bool fWindowActive; + bool fURLLocked; }; #endif // URL_INPUT_GROUP_H