linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #03886
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2492: rework tab activation to fix latent bugs: only top-level windows can be activated, others can onl...
------------------------------------------------------------
revno: 2492
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Fri 2011-04-15 23:51:55 +0200
message:
rework tab activation to fix latent bugs: only top-level windows can be activated, others can only be focused
modified:
changelog.txt
dwt/include/dwt/Taskbar.h
dwt/include/dwt/aspects/AspectEraseBackground.h
dwt/include/dwt/forward.h
dwt/include/dwt/widgets/Composite.h
dwt/include/dwt/widgets/Frame.h
dwt/src/Taskbar.cpp
dwt/src/widgets/TabView.cpp
win32/DirectoryListingFrame.cpp
win32/FinishedFrameBase.h
win32/MDIChildFrame.h
win32/MainWindow.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2011-04-11 21:26:22 +0000
+++ changelog.txt 2011-04-15 21:51:55 +0000
@@ -18,6 +18,8 @@
* Make more parts of the interface DPI-aware (poy)
* Resizable and scrollable settings dialog
* Remember the last settings page (poy)
+* Fix focus problems in dialogs (poy)
+* Fix Ctrl+W / Ctrl+F4 sometimes closing the wrong tab (poy)
-- 0.782 2011-03-05 --
* Prevent a remote crash triggered via malformed user commands (poy)
=== modified file 'dwt/include/dwt/Taskbar.h'
--- dwt/include/dwt/Taskbar.h 2011-01-02 17:12:02 +0000
+++ dwt/include/dwt/Taskbar.h 2011-04-15 21:51:55 +0000
@@ -64,7 +64,7 @@
virtual void setActive(ContainerPtr) = 0;
WindowPtr window;
- std::unordered_map<ContainerPtr, ContainerPtr> tabs;
+ std::unordered_map<ContainerPtr, FramePtr> tabs;
};
}
=== modified file 'dwt/include/dwt/aspects/AspectEraseBackground.h'
--- dwt/include/dwt/aspects/AspectEraseBackground.h 2011-02-19 17:02:21 +0000
+++ dwt/include/dwt/aspects/AspectEraseBackground.h 2011-04-15 21:51:55 +0000
@@ -38,6 +38,7 @@
#include "../Message.h"
#include "../CanvasClasses.h"
+#include "../Dispatchers.h"
namespace dwt {
=== modified file 'dwt/include/dwt/forward.h'
--- dwt/include/dwt/forward.h 2011-04-05 19:16:53 +0000
+++ dwt/include/dwt/forward.h 2011-04-15 21:51:55 +0000
@@ -79,6 +79,9 @@
class FontDialog;
+class Frame;
+typedef Frame* FramePtr;
+
class Grid;
typedef Grid* GridPtr;
class GridInfo;
=== modified file 'dwt/include/dwt/widgets/Composite.h'
--- dwt/include/dwt/widgets/Composite.h 2011-01-02 17:12:02 +0000
+++ dwt/include/dwt/widgets/Composite.h 2011-04-15 21:51:55 +0000
@@ -32,7 +32,6 @@
#ifndef DWT_COMPOSITE_H_
#define DWT_COMPOSITE_H_
-#include "../aspects/AspectActivate.h"
#include "../aspects/AspectContainer.h"
#include "../aspects/AspectEraseBackground.h"
#include "../aspects/AspectText.h"
@@ -45,7 +44,6 @@
class Composite :
public Control,
// Aspects
- public AspectActivate<Composite>,
public AspectContainer<Composite>,
public AspectEraseBackground<Composite>,
public AspectText<Composite>
=== modified file 'dwt/include/dwt/widgets/Frame.h'
--- dwt/include/dwt/widgets/Frame.h 2011-01-02 17:12:02 +0000
+++ dwt/include/dwt/widgets/Frame.h 2011-04-15 21:51:55 +0000
@@ -37,39 +37,16 @@
#define DWT_Frame_h
#include "../resources/Icon.h"
+#include "../aspects/AspectActivate.h"
#include "../aspects/AspectMinMax.h"
#include "Composite.h"
namespace dwt {
-/// Main Window class
-/** \ingroup WidgetControls
- * \WidgetUsageInfo
- * \image html widgetwindow.png
- * This class defines a "normal" window or the most commonly used "container
- * Widget", normally you would define your own class which (indirectly) derives from
- * this one. <br>
- * You would normally derive directly from WidgetFactory and then supply this class
- * as the first template parameter. <br>
- * The second parameter would then be YOUR CLASS. <br>
- * Example <br>
- * <b>class MyMainWindow : public dwt::WidgetFactory<dwt::Window,
- * MyMainWindow> { ... };</b> <br>
- * Note especially that the second template argument to the WidgetFactory template
- * class would almost ALWAYS be the name of your class derived from WidgetFactory.
- * <br>
- * You can also derive directly from Window and skip around the WidgetFactory
- * factory class, the inheritance string would then become: <br>
- * <b>class MyMainWindow : public dwt::Window<MyMainWindow></b> <br>
- * But then you wouldn't have access to all the "createxxx" functions from class
- * WidgetFactory which automatically gurantees that your Widgets get the right parent
- * etc. <br>
- * Look at (almost) any of the example projects distributed with the main download of
- * the library residing in the dwtUnitTests directory for an example of how to
- * use this class with the factory class WidgetFactory.
- */
+/** Base class for a top-level window (either a main app window or a dialog). */
class Frame :
public Composite,
+ public AspectActivate<Frame>,
public AspectMinMax<Frame>
{
typedef Composite BaseType;
=== modified file 'dwt/src/Taskbar.cpp'
--- dwt/src/Taskbar.cpp 2011-03-02 16:06:03 +0000
+++ dwt/src/Taskbar.cpp 2011-04-15 21:51:55 +0000
@@ -113,6 +113,24 @@
}
}
+class Proxy : public Frame {
+ typedef Frame BaseType;
+ friend class WidgetCreator<Proxy>;
+
+public:
+ typedef Proxy ThisType;
+ typedef ThisType* ObjectType;
+ struct Seed : BaseType::Seed {
+ typedef ThisType WidgetType;
+ Seed(const tstring& caption) : BaseType::Seed(caption, 0, 0) {
+ style = WS_POPUP | WS_CAPTION;
+ exStyle = WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE;
+ location = Rectangle();
+ }
+ };
+ Proxy(Widget* parent) : BaseType(parent, NormalDispatcher::getDefault()) { }
+};
+
void Taskbar::addToTaskbar(ContainerPtr tab) {
/* for Windows to acknowledge that our tab window is worthy of having its own thumbnail in the
taskbar, we have to create an invisible popup window that will act as a proxy between the
@@ -120,16 +138,7 @@
this technique is illustrated in MFC as well as the Windows SDK sample at
"Samples\winui\shell\appshellintegration\TabThumbnails". */
- ContainerPtr proxy;
- {
- Container::Seed seed;
- seed.caption = tab->getText();
- seed.style &= ~WS_VISIBLE;
- seed.style |= WS_POPUP | WS_CAPTION;
- seed.exStyle |= WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE;
- seed.location = Rectangle();
- proxy = window->addChild(seed);
- }
+ auto proxy = window->addChild(Proxy::Seed(tab->getText()));
tabs[tab] = proxy;
// keep the proxy window in sync with the actual tab window.
@@ -187,9 +196,9 @@
}
void Taskbar::removeFromTaskbar(ContainerPtr tab) {
- ContainerPtr proxy = tabs[tab];
+ auto proxy = tabs[tab];
taskbar->UnregisterTab(proxy->handle());
- ::DestroyWindow(proxy->handle());
+ proxy->close();
tabs.erase(tab);
}
=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp 2011-03-30 20:13:51 +0000
+++ dwt/src/widgets/TabView.cpp 2011-04-15 21:51:55 +0000
@@ -296,10 +296,9 @@
newW->resize(clientSize);
newW->setVisible(true);
if(oldW) {
- oldW->sendMessage(WM_ACTIVATE, WA_INACTIVE, reinterpret_cast<LPARAM>(newW->handle()));
oldW->setVisible(false);
}
- newW->sendMessage(WM_ACTIVATE, WA_ACTIVE, oldW ? reinterpret_cast<LPARAM>(oldW->handle()) : 0);
+ newW->setFocus();
}
void TabView::handleTabSelected() {
=== modified file 'win32/DirectoryListingFrame.cpp'
--- win32/DirectoryListingFrame.cpp 2011-04-13 19:16:51 +0000
+++ win32/DirectoryListingFrame.cpp 2011-04-15 21:51:55 +0000
@@ -112,7 +112,7 @@
frame->activate();
} else {
frame->setDirty(SettingsManager::BOLD_FL);
- frame->onActivate([frame, aDir](bool b) {
+ frame->onVisibilityChanged([frame, aDir](bool b) {
if(b && !frame->loaded && !WinUtil::mainWindow->closing())
frame->loadFile(aDir);
});
=== modified file 'win32/FinishedFrameBase.h'
--- win32/FinishedFrameBase.h 2011-04-05 19:16:53 +0000
+++ win32/FinishedFrameBase.h 2011-04-15 21:51:55 +0000
@@ -134,7 +134,7 @@
onlyFull->onClicked([this] { this->handleOnlyFullClicked(); });
}
- filesWindow->onActivate([this](bool active) { this->onlyFull->setVisible(active); });
+ filesWindow->onVisibilityChanged([this](bool b) { this->onlyFull->setVisible(b); });
}
this->initStatus();
@@ -148,8 +148,8 @@
layout();
- filesWindow->onActivate([this](bool active) { this->updateStatus(active); });
- usersWindow->onActivate([this](bool active) { this->updateStatus(active); });
+ filesWindow->onVisibilityChanged([this](bool b) { if(b) this->updateStatus(); });
+ usersWindow->onVisibilityChanged([this](bool b) { if(b) this->updateStatus(); });
FinishedManager::getInstance()->addListener(this);
@@ -524,10 +524,7 @@
updateStatus();
}
- void updateStatus(bool activate = true) {
- if(!activate)
- return;
-
+ void updateStatus() {
size_t count = 0;
int64_t bytes = 0;
int64_t time = 0;
=== modified file 'win32/MDIChildFrame.h'
--- win32/MDIChildFrame.h 2011-04-05 19:16:53 +0000
+++ win32/MDIChildFrame.h 2011-04-15 21:51:55 +0000
@@ -60,8 +60,8 @@
onClosing([this] { return this->handleClosing(); });
onFocus([this] { this->handleFocus(); });
+ onVisibilityChanged([this](bool b) { this->handleVisibilityChanged(b); });
onWindowPosChanged([this](const dwt::Rectangle &r) { this->handleSized(r); });
- onActivate([this](bool active) { this->handleActivate(active); });
addDlgCodeMessage(this);
addAccel(FCONTROL, 'W', [this] { this->close(true); });
@@ -74,12 +74,6 @@
getParent()->remove(this);
}
- void handleFocus() {
- if(lastFocus != NULL) {
- ::SetFocus(lastFocus);
- }
- }
-
/**
* The first of two close phases, used to disconnect from other threads that might affect this window.
* This is where all stuff that might be affected by other threads goes - it should make sure
@@ -195,14 +189,17 @@
t().layout();
}
- void handleActivate(bool active) {
- if(active) {
- if(lastFocus) {
- ::SetFocus(lastFocus);
- }
- } else if(!alwaysSameFocus) {
+ void handleFocus() {
+ if(lastFocus) {
+ ::SetFocus(lastFocus);
+ }
+ }
+
+ void handleVisibilityChanged(bool b) {
+ if(!b && !alwaysSameFocus) {
+ // remember the previously focused window.
HWND focus = ::GetFocus();
- if(focus != NULL && ::IsChild(t().handle(), focus))
+ if(focus && ::IsChild(t().handle(), focus))
lastFocus = focus;
}
}
=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp 2011-04-15 20:53:17 +0000
+++ win32/MainWindow.cpp 2011-04-15 21:51:55 +0000
@@ -1079,10 +1079,10 @@
}
void MainWindow::handleActivate(bool active) {
- // Forward to active tab window
+ // focus the active tab window
Container* w = getTabView()->getActive();
if(w) {
- w->sendMessage(WM_ACTIVATE, active ? WA_ACTIVE : WA_INACTIVE);
+ w->setFocus();
}
}