* Moved workspace keyboard switch and dump screen capability from RootLayer

into a Desktop keyboard filter.
* Removed keyboard handling code from RootLayer and Layer.
* Renamed Desktop::ActiveRootLayer() to RootLayer() as there is only one
  root layer per desktop.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15018 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-11-18 13:51:32 +00:00
parent f68598780e
commit fa26723bb2
10 changed files with 124 additions and 214 deletions

View File

@ -30,6 +30,7 @@
#include <WindowInfo.h>
#include <ServerProtocol.h>
#include <Entry.h>
#include <Message.h>
#include <MessageFilter.h>
#include <Region.h>
@ -48,6 +49,98 @@
#endif
class KeyboardFilter : public BMessageFilter {
public:
KeyboardFilter(Desktop* desktop);
virtual filter_result Filter(BMessage* message, BHandler** _target);
private:
Desktop* fDesktop;
};
KeyboardFilter::KeyboardFilter(Desktop* desktop)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
fDesktop(desktop)
{
}
filter_result
KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/)
{
int32 key;
int32 modifiers;
if (message->what != B_KEY_DOWN
|| message->FindInt32("key", &key) != B_OK
|| message->FindInt32("modifiers", &modifiers) != B_OK)
return B_DISPATCH_MESSAGE;
// Check for safe video mode (F12 + l-cmd + l-ctrl + l-shift)
if (key == 0x0d
&& (modifiers & (B_LEFT_COMMAND_KEY
| B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0)
{
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN.
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
return B_SKIP_MESSAGE;
}
if (key > 0x01 && key < 0x0e) {
// workspace change, F1-F12
#if !TEST_MODE
if (modifiers & B_COMMAND_KEY)
#else
if (modifiers & B_CONTROL_KEY)
#endif
{
STRACE(("Set Workspace %ld\n", key - 1));
RootLayer* root = fDesktop->RootLayer();
root->Lock();
root->SetActiveWorkspace(key - 2);
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
// to draw the current Workspace index on screen.
BRegion region(VisibleRegion());
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(&region);
root->Draw(region.Frame());
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(NULL);
#endif
root->Unlock();
return B_SKIP_MESSAGE;
}
}
// TODO: this should be moved client side!
// (that's how it is done in BeOS, clients could need this key for
// different purposes - also, it's preferrable to let the client
// write the dump within his own environment)
if (key == 0xe) {
// screen dump, PrintScreen
char filename[128];
BEntry entry;
int32 index = 1;
do {
sprintf(filename, "/boot/home/screen%ld.png", index++);
entry.SetTo(filename);
} while(entry.Exists());
fDesktop->GetDrawingEngine()->DumpToFile(filename);
return B_SKIP_MESSAGE;
}
return B_DISPATCH_MESSAGE;
}
// #pragma mark -
Desktop::Desktop(uid_t userID)
: MessageLooper("desktop"),
fUserID(userID),
@ -94,7 +187,7 @@ Desktop::Init()
// TODO: add user identity to the name
char name[32];
sprintf(name, "RootLayer %d", 1);
fRootLayer = new RootLayer(name, 4, this, GetDrawingEngine());
fRootLayer = new ::RootLayer(name, 4, this, GetDrawingEngine());
#if TEST_MODE
gInputManager->AddStream(new InputServerStream);
@ -105,7 +198,7 @@ Desktop::Init()
// temporary hack to get things started
class MouseFilter : public BMessageFilter {
public:
MouseFilter(RootLayer* layer)
MouseFilter(::RootLayer* layer)
: BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
fRootLayer(layer)
{
@ -121,9 +214,10 @@ Desktop::Init()
}
private:
RootLayer* fRootLayer;
::RootLayer* fRootLayer;
};
fEventDispatcher.SetMouseFilter(new MouseFilter(fRootLayer));
fEventDispatcher.SetKeyboardFilter(new KeyboardFilter(this));
// take care of setting the default cursor
ServerCursor *cursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT);
@ -394,20 +488,17 @@ Desktop::AddWinBorder(WinBorder *winBorder)
if (!winBorder)
return;
// R2: how to determine the RootLayer to which this window should be added???
// for now, use ActiveRootLayer() because we only have one instance.
int32 feel = winBorder->Feel();
// we are ServerApp thread, we need to lock RootLayer here.
ActiveRootLayer()->Lock();
RootLayer()->Lock();
// we're playing with window list. lock first.
Lock();
if (fWinBorderList.HasItem(winBorder)) {
Unlock();
ActiveRootLayer()->Unlock();
RootLayer()->Unlock();
debugger("AddWinBorder: WinBorder already in Desktop list\n");
return;
}
@ -443,12 +534,12 @@ Desktop::AddWinBorder(WinBorder *winBorder)
}
// send WinBorder to be added to workspaces
ActiveRootLayer()->AddWinBorder(winBorder);
RootLayer()->AddWinBorder(winBorder);
// hey, unlock!
Unlock();
ActiveRootLayer()->Unlock();
RootLayer()->Unlock();
}
@ -459,7 +550,7 @@ Desktop::RemoveWinBorder(WinBorder *winBorder)
return;
// we are ServerApp thread, we need to lock RootLayer here.
ActiveRootLayer()->Lock();
RootLayer()->Lock();
// we're playing with window list. lock first.
Lock();
@ -494,16 +585,16 @@ Desktop::RemoveWinBorder(WinBorder *winBorder)
}
} else {
Unlock();
ActiveRootLayer()->Unlock();
RootLayer()->Unlock();
debugger("RemoveWinBorder: WinBorder not found in Desktop list\n");
return;
}
// Tell to winBorder's RootLayer about this.
ActiveRootLayer()->RemoveWinBorder(winBorder);
RootLayer()->RemoveWinBorder(winBorder);
Unlock();
ActiveRootLayer()->Unlock();
RootLayer()->Unlock();
}
@ -538,7 +629,7 @@ Desktop::AddWinBorderToSubset(WinBorder *winBorder, WinBorder *toWinBorder)
}
// send WinBorder to be added to workspaces, if not already in there.
ActiveRootLayer()->AddSubsetWinBorder(winBorder, toWinBorder);
RootLayer()->AddSubsetWinBorder(winBorder, toWinBorder);
Unlock();
}
@ -562,7 +653,7 @@ Desktop::RemoveWinBorderFromSubset(WinBorder *winBorder, WinBorder *fromWinBorde
}
// remove WinBorder from workspace, if needed - some other windows may still have it in their subset
ActiveRootLayer()->RemoveSubsetWinBorder(winBorder, fromWinBorder);
RootLayer()->RemoveSubsetWinBorder(winBorder, fromWinBorder);
if (fromWinBorder->Feel() == B_NORMAL_WINDOW_FEEL) {
//remove from this normal_window's subset.

View File

@ -60,7 +60,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
{ return fActiveScreen; }
inline Screen* ActiveScreen() const
{ return fActiveScreen; }
inline RootLayer* ActiveRootLayer() const { return fRootLayer; }
inline ::RootLayer* RootLayer() const { return fRootLayer; }
inline CursorManager& GetCursorManager() { return fCursorManager; }
virtual void ScreenRemoved(Screen* screen) {}
@ -116,7 +116,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
BObjectList<WinBorder> fWinBorderList;
RootLayer* fRootLayer;
::RootLayer* fRootLayer;
Screen* fActiveScreen;
CursorManager fCursorManager;

View File

@ -61,7 +61,7 @@ EventDispatcher::EventDispatcher()
fTransit(false),
fSuspendFocus(false),
fMouseFilter(NULL),
fKeyFilter(NULL),
fKeyboardFilter(NULL),
fListeners(10, true),
// the list owns its items
fCursorLock("cursor loop lock"),
@ -322,15 +322,15 @@ EventDispatcher::SetMouseFilter(BMessageFilter* filter)
void
EventDispatcher::SetKeyFilter(BMessageFilter* filter)
EventDispatcher::SetKeyboardFilter(BMessageFilter* filter)
{
BAutolock _(this);
if (fKeyFilter == filter)
if (fKeyboardFilter == filter)
return;
delete fKeyFilter;
fKeyFilter = filter;
delete fKeyboardFilter;
fKeyboardFilter = filter;
}
@ -501,8 +501,8 @@ EventDispatcher::_EventLoop()
case B_UNMAPPED_KEY_DOWN:
case B_UNMAPPED_KEY_UP:
case B_MODIFIERS_CHANGED:
if (fKeyFilter != NULL
&& fKeyFilter->Filter(event, NULL) == B_SKIP_MESSAGE)
if (fKeyboardFilter != NULL
&& fKeyboardFilter->Filter(event, NULL) == B_SKIP_MESSAGE)
break;
keyboardEvent = true;

View File

@ -36,7 +36,7 @@ class EventDispatcher : public BLocker {
void RemoveListener(BMessenger& messenger, int32 token);
void SetMouseFilter(BMessageFilter* filter);
void SetKeyFilter(BMessageFilter* filter);
void SetKeyboardFilter(BMessageFilter* filter);
bool HasCursorThread();
void SetHWInterface(HWInterface* interface);
@ -81,7 +81,7 @@ class EventDispatcher : public BLocker {
bool fSuspendFocus;
BMessageFilter* fMouseFilter;
BMessageFilter* fKeyFilter;
BMessageFilter* fKeyboardFilter;
BObjectList<event_target> fListeners;

View File

@ -806,45 +806,6 @@ Layer::MouseWheelChanged(const BMessage *msg)
}
}
void
Layer::KeyDown(const BMessage *msg)
{
if (Window() && !IsTopLayer()) {
Window()->SendMessageToClient(msg, B_NULL_TOKEN, true);
}
}
void
Layer::KeyUp(const BMessage *msg)
{
if (Window() && !IsTopLayer()) {
Window()->SendMessageToClient(msg, B_NULL_TOKEN, true);
}
}
void
Layer::UnmappedKeyDown(const BMessage *msg)
{
if (Window() && !IsTopLayer()) {
Window()->SendMessageToClient(msg, B_NULL_TOKEN, true);
}
}
void
Layer::UnmappedKeyUp(const BMessage *msg)
{
if (Window() && !IsTopLayer()) {
Window()->SendMessageToClient(msg, B_NULL_TOKEN, true);
}
}
void
Layer::ModifiersChanged(const BMessage *msg)
{
if (Window() && !IsTopLayer()) {
Window()->SendMessageToClient(msg, B_NULL_TOKEN, true);
}
}
void
Layer::WorkspaceActivated(int32 index, bool active)

View File

@ -146,12 +146,6 @@ class Layer {
virtual void MouseMoved(const BMessage *msg);
virtual void MouseWheelChanged(const BMessage *msg);
virtual void KeyDown(const BMessage *msg);
virtual void KeyUp(const BMessage *msg);
virtual void UnmappedKeyDown(const BMessage *msg);
virtual void UnmappedKeyUp(const BMessage *msg);
virtual void ModifiersChanged(const BMessage *msg);
virtual void WorkspaceActivated(int32 index, bool active);
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
virtual void Activated(bool active);

View File

@ -18,7 +18,7 @@
#include <Window.h>
#include <List.h>
#include <Message.h>
#include <Entry.h>
//#include <Entry.h>
#include <File.h>
#include <PortLink.h>
@ -1056,134 +1056,6 @@ RootLayer::MouseEventHandler(BMessage *msg)
}
void
RootLayer::KeyboardEventHandler(BMessage *msg)
{
switch (msg->what) {
case B_KEY_DOWN:
{
int32 scancode = 0;
int32 modifiers = 0;
msg->FindInt32("key", &scancode);
msg->FindInt32("modifiers", &modifiers);
// F1-F12
if (scancode > 0x01 && scancode < 0x0e) {
// Check for workspace change or safe video mode
if (scancode == 0x0d && (modifiers & (B_LEFT_COMMAND_KEY
| B_LEFT_CONTROL_KEY | B_LEFT_SHIFT_KEY)) != 0)
{
// TODO: Set to Safe Mode in KeyboardEventHandler:B_KEY_DOWN. (DrawingEngine API change)
STRACE(("Safe Video Mode invoked - code unimplemented\n"));
break;
}
#if !TEST_MODE
if (modifiers & B_COMMAND_KEY)
#else
if (modifiers & B_CONTROL_KEY)
#endif
{
STRACE(("Set Workspace %ld\n",scancode-1));
SetActiveWorkspace(scancode - 2);
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
// to draw the current Workspace index on screen.
BRegion reg(VisibleRegion());
fDriver->ConstrainClippingRegion(&reg);
Draw(reg.Frame());
fDriver->ConstrainClippingRegion(NULL);
#endif
break;
}
}
// Tab key
if (scancode == 0x26 && (modifiers & B_CONTROL_KEY)) {
STRACE(("Twitcher\n"));
//ServerApp *deskbar = app_server->FindApp("application/x-vnd.Be-TSKB");
//if(deskbar)
//{
// TODO: implement;
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
break;
//}
}
// PrintScreen
if (scancode == 0xe) {
if (GetDrawingEngine()) {
char filename[128];
BEntry entry;
int32 index = 1;
do {
sprintf(filename, "/boot/home/screen%ld.png", index++);
entry.SetTo(filename);
} while(entry.Exists());
GetDrawingEngine()->DumpToFile(filename);
break;
}
}
// We got this far, so apparently it's safe to pass to the active
// window.
if (Focus())
Focus()->KeyDown(msg);
break;
}
case B_KEY_UP:
{
int32 scancode = 0;
int32 modifiers = 0;
msg->FindInt32("key", &scancode);
msg->FindInt32("modifiers", &modifiers);
// Tab key
if (scancode == 0x26 && (modifiers & B_CONTROL_KEY)) {
//ServerApp *deskbar=app_server->FindApp("application/x-vnd.Be-TSKB");
//if(deskbar)
//{
printf("Send Twitcher message key to Deskbar - unimplmemented\n");
break;
//}
}
// We got this far, so apparently it's safe to pass to the active
// window.
if (Focus())
Focus()->KeyUp(msg);
break;
}
case B_UNMAPPED_KEY_DOWN:
if (Focus())
Focus()->UnmappedKeyDown(msg);
break;
case B_UNMAPPED_KEY_UP:
if (Focus())
Focus()->UnmappedKeyUp(msg);
break;
case B_MODIFIERS_CHANGED:
if (Focus())
Focus()->ModifiersChanged(msg);
break;
default:
break;
}
}
bool
RootLayer::AddToInputNotificationLists(Layer *lay, uint32 mask, uint32 options)
{

View File

@ -123,10 +123,6 @@ public:
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
// BRegion fRedrawReg;
// BList fCopyRegList;
// BList fCopyList;
private:
friend class Desktop;
@ -143,8 +139,6 @@ friend class Desktop;
// Input related methods
void MouseEventHandler(BMessage *msg);
void KeyboardEventHandler(BMessage *msg);
void _ProcessMouseMovedEvent(BMessage *msg);
Desktop* fDesktop;

View File

@ -847,7 +847,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
STRACE(("ServerApp %s: get current workspace\n", Signature()));
// TODO: Locking this way is not nice
RootLayer *root = fDesktop->ActiveRootLayer();
RootLayer *root = fDesktop->RootLayer();
root->Lock();
fLink.StartMessage(SERVER_TRUE);
@ -865,7 +865,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// TODO: See above
int32 index;
link.Read<int32>(&index);
RootLayer *root = fDesktop->ActiveRootLayer();
RootLayer *root = fDesktop->RootLayer();
root->Lock();
root->SetActiveWorkspace(index);
root->Unlock();
@ -2098,9 +2098,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
bool makedefault = false;
link.Read<bool>(&makedefault);
// TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping
// optionally put this into a message and let the root layer thread handle it.
RootLayer* rootLayer = fDesktop->ActiveRootLayer();
RootLayer* rootLayer = fDesktop->RootLayer();
rootLayer->Lock();
status_t status = fDesktop->ScreenAt(0)->SetMode(mode);
if (status == B_OK) {
@ -2189,7 +2187,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// ToDo: locking is probably wrong - why the hell is there no (safe)
// way to get to the workspace object directly?
RootLayer *root = fDesktop->ActiveRootLayer();
RootLayer *root = fDesktop->RootLayer();
root->Lock();
Workspace *workspace;

View File

@ -1587,7 +1587,7 @@ if (myRootLayer)
// 2) int32 button state
fLink.Attach<BPoint>(fDesktop->HWInterface()->GetCursorPosition());
fLink.Attach<int32>(fDesktop->ActiveRootLayer()->Buttons());
fLink.Attach<int32>(fDesktop->RootLayer()->Buttons());
fLink.Flush();
break;