/* * Workspaces.cpp * Open BeOS version alpha 1 by Francois Revol revol@free.fr * * Workspaces window trick found by Michael "Minox" Paine. * (using B_ALL_WORKSPACES as flags in BWindow) * Found out that using 0xffffffff as Flags was causing the window not to close on Alt-W * hey Workspaces get Flags of Window 0 * gives 0x00008080 which makes it. */ #include #include #include #include #include #include #include #include #include #include class WorkspacesPreferences { public: WorkspacesPreferences(); virtual ~WorkspacesPreferences(); BRect WindowFrame() const { return fWindowFrame; } BRect ScreenFrame() const { return fScreenFrame; } void UpdateScreenFrame(); void SetWindowFrame(BRect); private: static const char kWorkspacesSettingFile[]; BRect fWindowFrame, fScreenFrame; }; class WorkspacesWindow : public BWindow { public: WorkspacesWindow(WorkspacesPreferences *fPreferences); virtual ~WorkspacesWindow(); virtual void ScreenChanged(BRect frame,color_space mode); virtual void FrameMoved(BPoint origin); virtual void FrameResized(float width, float height); virtual void Zoom(BPoint origin, float width, float height); virtual void MessageReceived(BMessage *msg); virtual bool QuitRequested(void); private: WorkspacesPreferences *fPreferences; }; class WorkspacesApp : public BApplication { public: WorkspacesApp(); virtual ~WorkspacesApp(); virtual void AboutRequested(void); virtual void ArgvReceived(int32 argc, char **argv); virtual void ReadyToRun(void); virtual bool WorkspacesApp::QuitRequested(void); private: static const char kWorkspacesAppSig[]; }; const char WorkspacesApp::kWorkspacesAppSig[] = "application/x-vnd.Be-WORK"; const char WorkspacesPreferences::kWorkspacesSettingFile[] = "Workspace_data"; WorkspacesPreferences::WorkspacesPreferences() { UpdateScreenFrame(); BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) == B_OK) { path.Append(kWorkspacesSettingFile); BFile file(path.Path(), B_READ_ONLY); if (file.InitCheck() == B_OK && file.Read(&fWindowFrame, sizeof(BRect)) == sizeof(BRect)) { BScreen screen; if (screen.Frame().right >= fWindowFrame.right && screen.Frame().bottom >= fWindowFrame.bottom) return; } } fWindowFrame = fScreenFrame; fWindowFrame.OffsetBy(-10, -10); fWindowFrame.left = fWindowFrame.right - 160; fWindowFrame.top = fWindowFrame.bottom - 120; } WorkspacesPreferences::~WorkspacesPreferences() { BPath path; if (find_directory(B_USER_SETTINGS_DIRECTORY,&path) < B_OK) return; path.Append(kWorkspacesSettingFile); BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE); if (file.InitCheck() == B_OK) file.Write(&fWindowFrame, sizeof(BRect)); } void WorkspacesPreferences::UpdateScreenFrame() { BScreen screen; fScreenFrame = screen.Frame(); } void WorkspacesPreferences::SetWindowFrame(BRect f) { fWindowFrame = f; UpdateScreenFrame(); } // #pragma mark - // here is the trick :) #define B_WORKSPACES_WINDOW 0x00008000 WorkspacesWindow::WorkspacesWindow(WorkspacesPreferences *preferences) : BWindow(preferences->WindowFrame(), "Workspaces", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_WORKSPACES_WINDOW | B_AVOID_FRONT, B_ALL_WORKSPACES) { fPreferences = preferences; } WorkspacesWindow::~WorkspacesWindow() { delete fPreferences; } void WorkspacesWindow::ScreenChanged(BRect frame,color_space mode) { BRect rect = fPreferences->WindowFrame(); BRect old = fPreferences->ScreenFrame(); // adjust horizontal position if (frame.right < rect.left || frame.right > rect.right && rect.left > old.right/2) MoveTo(frame.right - (old.right - rect.left),rect.top); // adjust vertical position if (frame.bottom < rect.top || frame.bottom > rect.bottom && rect.top > old.bottom/2) MoveTo(Frame().left,frame.bottom - (old.bottom - rect.top)); } void WorkspacesWindow::FrameMoved(BPoint origin) { fPreferences->SetWindowFrame(Frame()); } void WorkspacesWindow::FrameResized(float width, float height) { fPreferences->SetWindowFrame(Frame()); } void WorkspacesWindow::Zoom(BPoint origin, float width, float height) { BScreen screen; origin = screen.Frame().RightBottom(); origin.x -= 10 + fPreferences->WindowFrame().Width(); origin.y -= 10 + fPreferences->WindowFrame().Height(); MoveTo(origin); } void WorkspacesWindow::MessageReceived(BMessage *msg) { if (msg->what == 'DATA') { // Drop from Tracker entry_ref ref; for (int i = 0; (msg->FindRef("refs", i, &ref) == B_OK); i++) be_roster->Launch(&ref); } else BWindow::MessageReceived(msg); } bool WorkspacesWindow::QuitRequested(void) { be_app->PostMessage(B_QUIT_REQUESTED); return true; } // #pragma mark - WorkspacesApp::WorkspacesApp() : BApplication(kWorkspacesAppSig) { } WorkspacesApp::~WorkspacesApp() { } void WorkspacesApp::AboutRequested(void) { // blocking !! // the original does the same by the way =) (new BAlert("about", "OpenBeOS Workspaces\n\tby François Revol, Axel Dörfler.\n\noriginal Be version by Robert Polic", "Big Deal"))->Go(); } void WorkspacesApp::ArgvReceived(int32 argc, char **argv) { // we are told to switch to a specific workspace if (argc > 1) { // get it from the command line... activate_workspace(atoi(argv[1])); // if the app is running, don't quit // but if it isn't, cancel the complete run, so it doesn't // open any window if (IsLaunching()) Quit(); } } void WorkspacesApp::ReadyToRun(void) { (new WorkspacesWindow(new WorkspacesPreferences()))->Show(); } bool WorkspacesApp::QuitRequested(void) { return true; } // #pragma mark - int main(int argc, char **argv) { new WorkspacesApp(); be_app->Run(); delete be_app; return 0; }