6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30 trademarks of Be Incorporated in the United States and other countries. Other
31 brand product names are registered trademarks or trademarks of their respective
37 #include "BarWindow.h"
41 #include <Application.h>
42 #include <AutoDeleter.h>
44 #include <Directory.h>
45 #include <FindDirectory.h>
51 #include <MessageFilter.h>
52 #include <MessagePrivate.h>
56 #include "BarMenuBar.h"
58 #include "DeskbarUtils.h"
59 #include "DeskbarMenu.h"
60 #include "ExpandoMenuBar.h"
61 #include "StatusView.h"
63 #include "tracker_private.h"
65 #undef B_TRANSLATION_CONTEXT
66 #define B_TRANSLATION_CONTEXT "MainWindow"
69 // This is a very ugly hack to be able to call the private
70 // BMenuBar::StartMenuBar() method from the TBarWindow::ShowBeMenu() method.
71 // Don't do this at home -- but why the hell is this method private?
73 #define BMenuBar_StartMenuBar_Hack StartMenuBar__8BMenuBarFlbbP5BRect
75 #define BMenuBar_StartMenuBar_Hack StartMenuBar__8BMenuBarlbT2P5BRect
78 #define BMenuBar_StartMenuBar_Hack _ZN8BMenuBar12StartMenuBarEibbP5BRect
80 #define BMenuBar_StartMenuBar_Hack _ZN8BMenuBar12StartMenuBarElbbP5BRect
83 # error "You may want to port this ugly hack to your compiler ABI"
86 BMenuBar_StartMenuBar_Hack(BMenuBar
*, int32
, bool, bool, BRect
*);
89 TDeskbarMenu
* TBarWindow::sDeskbarMenu
= NULL
;
92 TBarWindow::TBarWindow()
94 BWindow(BRect(-1000.0f
, -1000.0f
, -1000.0f
, -1000.0f
),
95 B_TRANSLATE_SYSTEM_NAME("Deskbar"), B_BORDERED_WINDOW
,
96 B_WILL_ACCEPT_FIRST_CLICK
| B_NOT_ZOOMABLE
| B_NOT_CLOSABLE
97 | B_NOT_MINIMIZABLE
| B_NOT_MOVABLE
| B_NOT_V_RESIZABLE
98 | B_AVOID_FRONT
| B_ASYNCHRONOUS_CONTROLS
,
102 desk_settings
* settings
= ((TBarApp
*)be_app
)->Settings();
103 if (settings
->alwaysOnTop
)
104 SetFeel(B_FLOATING_ALL_WINDOW_FEEL
);
106 fBarView
= new TBarView(Bounds(), settings
->vertical
, settings
->left
,
107 settings
->top
, settings
->state
, settings
->width
);
110 RemoveShortcut('H', B_COMMAND_KEY
| B_CONTROL_KEY
);
111 AddShortcut('F', B_COMMAND_KEY
, new BMessage(kFindButton
));
116 TBarWindow::MenusBeginning()
122 if (GetDeskbarSettingsDirectory(path
) == B_OK
123 && path
.Append(kDeskbarMenuEntriesFileName
) == B_OK
124 && entry
.SetTo(path
.Path(), true) == B_OK
126 && entry
.GetRef(&ref
) == B_OK
) {
127 sDeskbarMenu
->SetNavDir(&ref
);
128 } else if (GetDeskbarDataDirectory(path
) == B_OK
129 && path
.Append(kDeskbarMenuEntriesFileName
) == B_OK
130 && entry
.SetTo(path
.Path(), true) == B_OK
132 && entry
.GetRef(&ref
) == B_OK
) {
133 sDeskbarMenu
->SetNavDir(&ref
);
135 // this really should never happen
140 sDeskbarMenu
->ResetTargets();
143 BWindow::MenusBeginning();
148 TBarWindow::MenusEnded()
150 fShowingMenu
= false;
151 BWindow::MenusEnded();
153 if (sDeskbarMenu
->LockLooper()) {
154 sDeskbarMenu
->ForceRebuild();
155 sDeskbarMenu
->UnlockLooper();
161 TBarWindow::MessageReceived(BMessage
* message
)
163 switch (message
->what
) {
166 BMessenger
tracker(kTrackerSignature
);
167 tracker
.SendMessage(message
);
172 GetLocation(message
);
175 case kMsgSetLocation
:
176 SetLocation(message
);
187 case kMsgGetItemInfo
:
209 GetIconFrame(message
);
213 BWindow::MessageReceived(message
);
220 TBarWindow::Minimize(bool minimize
)
222 // Don't allow the Deskbar to be minimized
224 BWindow::Minimize(false);
229 TBarWindow::FrameResized(float width
, float height
)
231 if (!fBarView
->Vertical())
232 return BWindow::FrameResized(width
, height
);
234 bool setToHiddenSize
= static_cast<TBarApp
*>(be_app
)->Settings()->autoHide
235 && fBarView
->IsHidden() && !fBarView
->DragRegion()->IsDragging();
236 if (!setToHiddenSize
) {
237 // constrain within limits
239 if (width
< gMinimumWindowWidth
)
240 newWidth
= gMinimumWindowWidth
;
241 else if (width
> gMaximumWindowWidth
)
242 newWidth
= gMaximumWindowWidth
;
246 float oldWidth
= static_cast<TBarApp
*>(be_app
)->Settings()->width
;
248 // update width setting
249 static_cast<TBarApp
*>(be_app
)->Settings()->width
= newWidth
;
251 if (oldWidth
!= newWidth
) {
252 fBarView
->ResizeTo(width
, fBarView
->Bounds().Height());
253 if (fBarView
->Vertical() && fBarView
->ExpandoState())
254 fBarView
->ExpandoMenuBar()->SetMaxContentWidth(width
);
256 fBarView
->UpdatePlacement();
263 TBarWindow::SaveSettings()
265 fBarView
->SaveSettings();
270 TBarWindow::QuitRequested()
272 be_app
->PostMessage(B_QUIT_REQUESTED
);
274 return BWindow::QuitRequested();
279 TBarWindow::WorkspaceActivated(int32 workspace
, bool active
)
281 BWindow::WorkspaceActivated(workspace
, active
);
283 if (active
&& !(fBarView
->ExpandoState() && fBarView
->Vertical()))
284 fBarView
->UpdatePlacement();
286 BRect screenFrame
= (BScreen(fBarView
->Window())).Frame();
287 fBarView
->SizeWindow(screenFrame
);
288 fBarView
->PositionWindow(screenFrame
);
289 fBarView
->Invalidate();
295 TBarWindow::ScreenChanged(BRect size
, color_space depth
)
297 BWindow::ScreenChanged(size
, depth
);
299 fBarView
->UpdatePlacement();
304 TBarWindow::SetDeskbarMenu(TDeskbarMenu
* menu
)
311 TBarWindow::DeskbarMenu()
318 TBarWindow::ShowDeskbarMenu()
320 BMenuBar
* menuBar
= fBarView
->BarMenuBar();
322 menuBar
= KeyMenuBar();
327 BMenuBar_StartMenuBar_Hack(menuBar
, 0, true, true, NULL
);
332 TBarWindow::ShowTeamMenu()
335 if (fBarView
->BarMenuBar() == NULL
)
338 if (KeyMenuBar() == NULL
)
341 BMenuBar_StartMenuBar_Hack(KeyMenuBar(), index
, true, true, NULL
);
345 // determines the actual location of the window
348 TBarWindow::DeskbarLocation() const
350 bool left
= fBarView
->Left();
351 bool top
= fBarView
->Top();
353 if (fBarView
->AcrossTop())
354 return B_DESKBAR_TOP
;
356 if (fBarView
->AcrossBottom())
357 return B_DESKBAR_BOTTOM
;
360 return B_DESKBAR_LEFT_TOP
;
363 return B_DESKBAR_RIGHT_TOP
;
366 return B_DESKBAR_LEFT_BOTTOM
;
368 return B_DESKBAR_RIGHT_BOTTOM
;
373 TBarWindow::GetLocation(BMessage
* message
)
375 BMessage
reply('rply');
376 reply
.AddInt32("location", (int32
)DeskbarLocation());
377 reply
.AddBool("expanded", fBarView
->ExpandoState());
379 message
->SendReply(&reply
);
384 TBarWindow::SetDeskbarLocation(deskbar_location location
, bool newExpandState
)
386 // left top and right top are the only two that
387 // currently pay attention to expand, ignore for all others
389 bool left
= false, top
= true, vertical
, expand
;
399 case B_DESKBAR_BOTTOM
:
406 case B_DESKBAR_LEFT_TOP
:
410 expand
= newExpandState
;
413 case B_DESKBAR_RIGHT_TOP
:
417 expand
= newExpandState
;
420 case B_DESKBAR_LEFT_BOTTOM
:
427 case B_DESKBAR_RIGHT_BOTTOM
:
442 fBarView
->ChangeState(expand
, vertical
, left
, top
);
447 TBarWindow::SetLocation(BMessage
* message
)
449 deskbar_location location
;
451 if (message
->FindInt32("location", (int32
*)&location
) == B_OK
452 && message
->FindBool("expand", &expand
) == B_OK
)
453 SetDeskbarLocation(location
, expand
);
458 TBarWindow::IsExpanded(BMessage
* message
)
460 BMessage
reply('rply');
461 reply
.AddBool("expanded", fBarView
->ExpandoState());
462 message
->SendReply(&reply
);
467 TBarWindow::Expand(BMessage
* message
)
470 if (message
->FindBool("expand", &expand
) == B_OK
) {
471 bool vertical
= fBarView
->Vertical();
472 bool left
= fBarView
->Left();
473 bool top
= fBarView
->Top();
474 fBarView
->ChangeState(expand
, vertical
, left
, top
);
480 TBarWindow::ItemInfo(BMessage
* message
)
486 if (message
->FindInt32("id", &id
) == B_OK
) {
487 if (fBarView
->ItemInfo(id
, &name
, &shelf
) == B_OK
) {
488 replyMsg
.AddString("name", name
);
490 replyMsg
.AddInt32("shelf", (int32
)shelf
);
493 } else if (message
->FindString("name", &name
) == B_OK
) {
494 if (fBarView
->ItemInfo(name
, &id
, &shelf
) == B_OK
) {
495 replyMsg
.AddInt32("id", id
);
497 replyMsg
.AddInt32("shelf", (int32
)shelf
);
502 message
->SendReply(&replyMsg
);
507 TBarWindow::ItemExists(BMessage
* message
)
515 if (message
->FindInt32("shelf", (int32
*)&shelf
) != B_OK
)
517 shelf
= B_DESKBAR_TRAY
;
520 if (message
->FindInt32("id", &id
) == B_OK
)
521 exists
= fBarView
->ItemExists(id
, shelf
);
522 else if (message
->FindString("name", &name
) == B_OK
)
523 exists
= fBarView
->ItemExists(name
, shelf
);
525 replyMsg
.AddBool("exists", exists
);
526 message
->SendReply(&replyMsg
);
531 TBarWindow::CountItems(BMessage
* message
)
536 if (message
->FindInt32("shelf", (int32
*)&shelf
) != B_OK
)
538 shelf
= B_DESKBAR_TRAY
;
540 BMessage
reply('rply');
541 reply
.AddInt32("count", fBarView
->CountItems(shelf
));
542 message
->SendReply(&reply
);
547 TBarWindow::AddItem(BMessage
* message
)
549 DeskbarShelf shelf
= B_DESKBAR_TRAY
;
553 status_t err
= B_ERROR
;
555 BMessage
* archivedView
= new BMessage();
556 ObjectDeleter
<BMessage
> deleter(archivedView
);
557 if (message
->FindMessage("view", archivedView
) == B_OK
) {
559 message
->FindInt32("shelf", &shelf
);
561 err
= fBarView
->AddItem(archivedView
, shelf
, &id
);
563 // Detach the deleter since AddReplicant is taking ownership
564 // on success. This should be changed on server side.
567 } else if (message
->FindRef("addon", &ref
) == B_OK
) {
569 err
= entry
.InitCheck();
571 err
= fBarView
->AddItem(&entry
, shelf
, &id
);
575 reply
.AddInt32("id", id
);
577 reply
.AddInt32("error", err
);
579 message
->SendReply(&reply
);
584 TBarWindow::RemoveItem(BMessage
* message
)
589 // ids ought to be unique across all shelves, assuming, of course,
590 // that sometime in the future there may be more than one
592 if (message
->FindInt32("shelf", (int32
*)&shelf
) == B_OK
) {
593 if (message
->FindString("name", &name
) == B_OK
)
594 fBarView
->RemoveItem(name
, shelf
);
597 if (message
->FindInt32("id", &id
) == B_OK
) {
598 fBarView
->RemoveItem(id
);
599 // remove the following two lines if and when the
600 // shelf option returns
601 } else if (message
->FindString("name", &name
) == B_OK
)
602 fBarView
->RemoveItem(name
, B_DESKBAR_TRAY
);
611 TBarWindow::GetIconFrame(BMessage
* message
)
613 BRect
frame(0, 0, 0, 0);
617 if (message
->FindInt32("id", &id
) == B_OK
)
618 frame
= fBarView
->IconFrame(id
);
619 else if (message
->FindString("name", &name
) == B_OK
)
620 frame
= fBarView
->IconFrame(name
);
622 BMessage
reply('rply');
623 reply
.AddRect("frame", frame
);
624 message
->SendReply(&reply
);
629 TBarWindow::IsShowingMenu() const
636 TBarWindow::_IsFocusMessage(BMessage
* message
)
638 BMessage::Private
messagePrivate(message
);
639 if (!messagePrivate
.UsePreferredTarget())
643 if (message
->HasInt32("_token")
644 && (message
->FindBool("_feed_focus", &feedFocus
) != B_OK
|| !feedFocus
))