Deskbar: Make Vulcan Death Grip work in mini-mode
Refactor so that ExpandoMenuBar and TeamMenu both call the menu item TeamMenuItem::HandleMouseDown() method to do the actual work and then send a message to cleanup. Fixes #17761 Change-Id: I0e13e5fc6c90236936120ff0dda1246123576d37 Reviewed-on: https://review.haiku-os.org/c/haiku/+/6311 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
6347519ab1
commit
4f97a431b9
@ -71,9 +71,6 @@ All rights reserved.
|
||||
#include "WindowMenuItem.h"
|
||||
|
||||
|
||||
const uint32 kMinimizeTeam = 'mntm';
|
||||
const uint32 kBringTeamToFront = 'bftm';
|
||||
|
||||
bool TExpandoMenuBar::sDoMonitor = false;
|
||||
thread_id TExpandoMenuBar::sMonThread = B_ERROR;
|
||||
BLocker TExpandoMenuBar::sMonLocker("expando monitor");
|
||||
@ -222,8 +219,7 @@ TExpandoMenuBar::MessageReceived(BMessage* message)
|
||||
break;
|
||||
|
||||
TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW,
|
||||
item->Teams(),
|
||||
item->Menu()->ConvertToScreen(item->Frame()),
|
||||
item->Teams(), item->Menu()->ConvertToScreen(item->Frame()),
|
||||
true);
|
||||
break;
|
||||
}
|
||||
@ -251,80 +247,57 @@ TExpandoMenuBar::MessageReceived(BMessage* message)
|
||||
void
|
||||
TExpandoMenuBar::MouseDown(BPoint where)
|
||||
{
|
||||
BMessage* message = Window()->CurrentMessage();
|
||||
BMenuItem* menuItem;
|
||||
TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem);
|
||||
fLastClickedItem = item;
|
||||
if (fBarView == NULL || fBarView->Dragging())
|
||||
return BMenuBar::MouseDown(where);
|
||||
|
||||
if (message == NULL || item == NULL || fBarView == NULL
|
||||
|| fBarView->Dragging()) {
|
||||
BMenuBar::MouseDown(where);
|
||||
return;
|
||||
}
|
||||
BMessage* message = Window()->CurrentMessage();
|
||||
BMenuItem* item = ItemAtPoint(where);
|
||||
fLastClickedItem = item;
|
||||
if (message == NULL || item == NULL)
|
||||
return BMenuBar::MouseDown(where);
|
||||
|
||||
int32 modifiers = 0;
|
||||
int32 buttons = 0;
|
||||
message->FindInt32("modifiers", &modifiers);
|
||||
message->FindInt32("buttons", &buttons);
|
||||
|
||||
// check for three finger salute, a.k.a. Vulcan Death Grip
|
||||
if ((modifiers & B_COMMAND_KEY) != 0
|
||||
&& (modifiers & B_CONTROL_KEY) != 0
|
||||
&& (modifiers & B_SHIFT_KEY) != 0) {
|
||||
const BList* teams = item->Teams();
|
||||
int32 teamCount = teams->CountItems();
|
||||
team_id teamID;
|
||||
for (int32 team = 0; team < teamCount; team++) {
|
||||
teamID = (addr_t)teams->ItemAt(team);
|
||||
kill_team(teamID);
|
||||
RemoveTeam(teamID, false);
|
||||
// remove the team from display immediately
|
||||
}
|
||||
return;
|
||||
// absorb the message
|
||||
} else if (item != NULL
|
||||
&& (modifiers & B_SHIFT_KEY) == 0
|
||||
// close window item
|
||||
if ((modifiers & B_SHIFT_KEY) != 0
|
||||
&& (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
|
||||
be_roster->Launch(item->Signature());
|
||||
return;
|
||||
// absorb the message
|
||||
} else {
|
||||
TWindowMenuItem* wndItem = dynamic_cast<TWindowMenuItem*>(menuItem);
|
||||
if (wndItem != NULL
|
||||
&& (modifiers & B_SHIFT_KEY) != 0
|
||||
&& (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
|
||||
// close window
|
||||
client_window_info* info;
|
||||
BMessenger wnd;
|
||||
info = get_window_info(wndItem->ID());
|
||||
if (info == NULL) return;
|
||||
BMessenger::Private(wnd).SetTo(
|
||||
info->team, info->client_port, info->client_token);
|
||||
free(info); info = NULL;
|
||||
wnd.SendMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
// absorb the message
|
||||
TWindowMenuItem* wItem = dynamic_cast<TWindowMenuItem*>(item);
|
||||
if (wItem != NULL) {
|
||||
// we have a window item
|
||||
BMessenger messenger;
|
||||
client_window_info* info = get_window_info(wItem->ID());
|
||||
if (info != NULL) {
|
||||
BMessenger::Private(messenger).SetTo(info->team,
|
||||
info->client_port, info->client_token);
|
||||
messenger.SendMessage(B_QUIT_REQUESTED);
|
||||
free(info);
|
||||
return;
|
||||
// absorb the message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// control click - show all/hide all shortcut
|
||||
if ((modifiers & B_CONTROL_KEY) != 0) {
|
||||
// show/hide item's teams
|
||||
BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
|
||||
? kMinimizeTeam : kBringTeamToFront);
|
||||
showMessage.AddInt32("itemIndex", IndexOf(item));
|
||||
Window()->PostMessage(&showMessage, this);
|
||||
// below depends on item being a team item
|
||||
|
||||
TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(item);
|
||||
if (teamItem == NULL)
|
||||
return BMenuBar::MouseDown(where);
|
||||
|
||||
// check for three finger salute, a.k.a. Vulcan Death Grip
|
||||
if (teamItem->HandleMouseDown(where))
|
||||
return;
|
||||
// absorb the message
|
||||
}
|
||||
|
||||
// check if within expander bounds to expand window items
|
||||
if (Vertical() && static_cast<TBarApp*>(be_app)->Settings()->superExpando
|
||||
&& item->ExpanderBounds().Contains(where)) {
|
||||
&& teamItem->ExpanderBounds().Contains(where)) {
|
||||
// start the animation here, finish on mouse up
|
||||
item->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW);
|
||||
teamItem->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW);
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
Invalidate(item->ExpanderBounds());
|
||||
Invalidate(teamItem->ExpanderBounds());
|
||||
return;
|
||||
// absorb the message
|
||||
}
|
||||
@ -335,9 +308,8 @@ TExpandoMenuBar::MouseDown(BPoint where)
|
||||
get_click_speed(&clickSpeed);
|
||||
bigtime_t delta = system_time() - fLastClickTime;
|
||||
if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1
|
||||
&& item == menuItem && item == fLastClickedItem
|
||||
&& delta <= clickSpeed) {
|
||||
be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0));
|
||||
&& item == fLastClickedItem && delta <= clickSpeed) {
|
||||
be_roster->ActivateApp((addr_t)teamItem->Teams()->ItemAt(0));
|
||||
// activate this team
|
||||
return;
|
||||
// absorb the message
|
||||
@ -489,15 +461,18 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
|
||||
void
|
||||
TExpandoMenuBar::MouseUp(BPoint where)
|
||||
{
|
||||
TTeamMenuItem* lastItem = dynamic_cast<TTeamMenuItem*>(fLastClickedItem);
|
||||
fLastClickedItem = NULL;
|
||||
|
||||
if (fBarView != NULL && fBarView->Dragging()) {
|
||||
_FinishedDrag(true);
|
||||
return;
|
||||
// absorb the message
|
||||
}
|
||||
|
||||
if (fLastClickedItem == NULL)
|
||||
return BMenuBar::MouseUp(where);
|
||||
|
||||
TTeamMenuItem* lastItem = dynamic_cast<TTeamMenuItem*>(fLastClickedItem);
|
||||
fLastClickedItem = NULL;
|
||||
|
||||
if (Vertical() && static_cast<TBarApp*>(be_app)->Settings()->superExpando
|
||||
&& lastItem != NULL && lastItem->ExpanderBounds().Contains(where)) {
|
||||
lastItem->ToggleExpandState(true);
|
||||
@ -507,6 +482,7 @@ TExpandoMenuBar::MouseUp(BPoint where)
|
||||
|
||||
Invalidate(lastItem->ExpanderBounds());
|
||||
}
|
||||
|
||||
BMenuBar::MouseUp(where);
|
||||
}
|
||||
|
||||
@ -626,6 +602,21 @@ TExpandoMenuBar::InDeskbarMenu(BPoint loc) const
|
||||
}
|
||||
|
||||
|
||||
BMenuItem*
|
||||
TExpandoMenuBar::ItemAtPoint(BPoint point)
|
||||
{
|
||||
int32 itemCount = CountItems();
|
||||
for (int32 index = 0; index < itemCount; index++) {
|
||||
BMenuItem* item = ItemAt(index);
|
||||
if (item != NULL && item->Frame().Contains(point))
|
||||
return item;
|
||||
}
|
||||
|
||||
// no item found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*! Returns the team menu item that belongs to the item under the
|
||||
specified \a point.
|
||||
If \a _item is given, it will return the exact menu item under
|
||||
@ -637,13 +628,12 @@ TExpandoMenuBar::TeamItemAtPoint(BPoint point, BMenuItem** _item)
|
||||
TTeamMenuItem* lastApp = NULL;
|
||||
int32 itemCount = CountItems();
|
||||
|
||||
for (int32 i = 0; i < itemCount; i++) {
|
||||
BMenuItem* item = ItemAt(i);
|
||||
for (int32 index = 0; index < itemCount; index++) {
|
||||
BMenuItem* item = ItemAt(index);
|
||||
if (item != NULL && item->Frame().Contains(point)) {
|
||||
if (dynamic_cast<TTeamMenuItem*>(item) != NULL)
|
||||
lastApp = (TTeamMenuItem*)item;
|
||||
|
||||
if (dynamic_cast<TTeamMenuItem*>(item) != NULL)
|
||||
lastApp = (TTeamMenuItem*)item;
|
||||
|
||||
if (item && item->Frame().Contains(point)) {
|
||||
if (_item != NULL)
|
||||
*_item = item;
|
||||
|
||||
|
@ -83,6 +83,7 @@ public:
|
||||
|
||||
void BuildItems();
|
||||
|
||||
BMenuItem* ItemAtPoint(BPoint point);
|
||||
TTeamMenuItem* TeamItemAtPoint(BPoint location,
|
||||
BMenuItem** _item = NULL);
|
||||
bool InDeskbarMenu(BPoint) const;
|
||||
|
@ -191,3 +191,64 @@ TTeamMenu::DetachedFromWindow()
|
||||
BMessenger self(this);
|
||||
TBarApp::Unsubscribe(self);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TTeamMenu::MessageReceived(BMessage* message)
|
||||
{
|
||||
TTeamMenuItem* item = NULL;
|
||||
|
||||
switch (message->what) {
|
||||
case B_SOME_APP_QUIT:
|
||||
case kRemoveTeam:
|
||||
{
|
||||
int32 itemIndex = -1;
|
||||
message->FindInt32("itemIndex", &itemIndex);
|
||||
team_id team = -1;
|
||||
message->FindInt32("team", &team);
|
||||
|
||||
item = dynamic_cast<TTeamMenuItem*>(ItemAt(itemIndex));
|
||||
if (item != NULL && item->Teams()->HasItem((void*)(addr_t)team)) {
|
||||
item->Teams()->RemoveItem(team);
|
||||
RemoveItem(itemIndex);
|
||||
delete item;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BMenu::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TTeamMenu::MouseDown(BPoint where)
|
||||
{
|
||||
if (fBarView == NULL || fBarView->Dragging())
|
||||
return BMenu::MouseDown(where);
|
||||
|
||||
BMenuItem* item = ItemAtPoint(where);
|
||||
if (item == NULL)
|
||||
return BMenu::MouseDown(where);
|
||||
|
||||
TTeamMenuItem* teamItem = dynamic_cast<TTeamMenuItem*>(item);
|
||||
if (teamItem == NULL || !teamItem->HandleMouseDown(where))
|
||||
BMenu::MouseDown(where);
|
||||
}
|
||||
|
||||
|
||||
BMenuItem*
|
||||
TTeamMenu::ItemAtPoint(BPoint point)
|
||||
{
|
||||
int32 itemCount = CountItems();
|
||||
for (int32 index = 0; index < itemCount; index++) {
|
||||
BMenuItem* item = ItemAt(index);
|
||||
if (item != NULL && item->Frame().Contains(point))
|
||||
return item;
|
||||
}
|
||||
|
||||
// no item found
|
||||
return NULL;
|
||||
}
|
||||
|
@ -50,8 +50,12 @@ class TTeamMenu : public BMenu {
|
||||
public:
|
||||
TTeamMenu(TBarView* barView = NULL);
|
||||
|
||||
void AttachedToWindow();
|
||||
void DetachedFromWindow();
|
||||
virtual void AttachedToWindow();
|
||||
virtual void DetachedFromWindow();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void MouseDown(BPoint where);
|
||||
|
||||
BMenuItem* ItemAtPoint(BPoint point);
|
||||
|
||||
static int CompareByName(const void* first,
|
||||
const void* second);
|
||||
|
@ -50,6 +50,7 @@ All rights reserved.
|
||||
#include <Region.h>
|
||||
#include <Roster.h>
|
||||
#include <Resources.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "BarApp.h"
|
||||
#include "BarMenuBar.h"
|
||||
@ -94,6 +95,67 @@ TTeamMenuItem::~TTeamMenuItem()
|
||||
}
|
||||
|
||||
|
||||
/*! Vulcan Death Grip and other team mouse button handling
|
||||
|
||||
\returns true if handled, false otherwise
|
||||
*/
|
||||
bool
|
||||
TTeamMenuItem::HandleMouseDown(BPoint where)
|
||||
{
|
||||
BMenu* menu = Menu();
|
||||
if (menu == NULL)
|
||||
return false;
|
||||
|
||||
BWindow* window = menu->Window();
|
||||
if (window == NULL)
|
||||
return false;
|
||||
|
||||
BMessage* message = window->CurrentMessage();
|
||||
if (message == NULL)
|
||||
return false;
|
||||
|
||||
int32 modifiers = 0;
|
||||
int32 buttons = 0;
|
||||
message->FindInt32("modifiers", &modifiers);
|
||||
message->FindInt32("buttons", &buttons);
|
||||
|
||||
// check for three finger salute, a.k.a. Vulcan Death Grip
|
||||
if ((modifiers & B_COMMAND_KEY) != 0
|
||||
&& (modifiers & B_CONTROL_KEY) != 0
|
||||
&& (modifiers & B_SHIFT_KEY) != 0) {
|
||||
BMessage appMessage(B_SOME_APP_QUIT);
|
||||
int32 teamCount = fTeam->CountItems();
|
||||
BMessage quitMessage(teamCount == 1 ? B_SOME_APP_QUIT : kRemoveTeam);
|
||||
quitMessage.AddInt32("itemIndex", menu->IndexOf(this));
|
||||
for (int32 index = 0; index < teamCount; index++) {
|
||||
team_id team = (addr_t)fTeam->ItemAt(index);
|
||||
appMessage.AddInt32("be:team", team);
|
||||
quitMessage.AddInt32("team", team);
|
||||
|
||||
kill_team(team);
|
||||
}
|
||||
be_app->PostMessage(&appMessage);
|
||||
TExpandoMenuBar* expando = dynamic_cast<TExpandoMenuBar*>(menu);
|
||||
window->PostMessage(&quitMessage, expando != NULL ? expando : menu);
|
||||
return true;
|
||||
} else if ((modifiers & B_SHIFT_KEY) == 0
|
||||
&& (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
|
||||
// launch new team
|
||||
be_roster->Launch(Signature());
|
||||
return true;
|
||||
} else if ((modifiers & B_CONTROL_KEY) != 0) {
|
||||
// control click - show all/hide all shortcut
|
||||
BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
|
||||
? kMinimizeTeam : kBringTeamToFront);
|
||||
showMessage.AddInt32("itemIndex", menu->IndexOf(this));
|
||||
window->PostMessage(&showMessage, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
TTeamMenuItem::Invoke(BMessage* message)
|
||||
{
|
||||
|
@ -46,6 +46,9 @@ All rights reserved.
|
||||
|
||||
const float kSwitchWidth = 12.0f;
|
||||
|
||||
const uint32 kMinimizeTeam = 'mntm';
|
||||
const uint32 kBringTeamToFront = 'bftm';
|
||||
|
||||
|
||||
class BBitmap;
|
||||
class TBarView;
|
||||
@ -60,6 +63,7 @@ public:
|
||||
float height = -1.0f);
|
||||
virtual ~TTeamMenuItem();
|
||||
|
||||
bool HandleMouseDown(BPoint where);
|
||||
status_t Invoke(BMessage* message = NULL);
|
||||
|
||||
void SetOverrideWidth(float width)
|
||||
|
Loading…
Reference in New Issue
Block a user