bool PropertyWriter::updateProperty (Window id, CompOption::Vector &propertyData, int type) { int count = 0; if (type != XA_STRING) { long int data[propertyData.size ()]; foreach (CompOption &o, propertyData) { switch (o.type ()) { case CompOption::TypeBool: data[count] = o.value ().b (); break; case CompOption::TypeInt: data[count] = o.value ().i (); break; default: data[count] = 0; break; } count++; } XChangeProperty (screen->dpy (), id, mAtom, type, 32, PropModeReplace, (unsigned char *)data, propertyData.size ()); }
bool RotateScreen::rotateTo (CompAction *action, CompAction::State state, CompOption::Vector &options, int face, bool withWindow) { CompOption::Vector o (0); if (face < 0) face = CompOption::getIntOptionNamed (options, "face", screen->vp ().x ()); if (face > screen->vpSize ().width ()) return false; o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (CompOption::getIntOptionNamed (options, "x", pointerX)); o[2].value ().set (CompOption::getIntOptionNamed (options, "y", pointerY)); if (withWindow) { o.push_back (CompOption ("window", CompOption::TypeInt)); o[3].value ().set (CompOption::getIntOptionNamed (options, "window", 0)); rotateWithWindow (NULL, 0, o, rotateToDirection (face)); } else rotate (NULL, 0, o, rotateToDirection (face)); return false; }
bool RotateScreen::rotateFlip (int direction) { if (screen->otherGrabExist ("rotate", "move", "group-drag", NULL)) return false; CompOption::Vector o (0); mMoveTo = 0.0f; mSlow = false; int warpX = pointerX - (screen->width () * direction); if (direction == -1) screen->warpPointer (screen->width () - 10, 0); else screen->warpPointer (10 - screen->width (), 0); lastPointerX = warpX; o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (0); o[2].value ().set (pointerY); rotate (NULL, 0, o, direction); XWarpPointer (screen->dpy (), None, None, 0, 0, 0, 0, direction, 0); mSavedPointer.setX (lastPointerX + (9 * direction)); return false; }
static void saveYourselfCallback (SmcConn connection, SmPointer client_data, int saveType, Bool shutdown, int interact_Style, Bool fast) { CompOption::Vector args; args.push_back (CompOption ("save_type", CompOption::TypeInt)); args.push_back (CompOption ("shutdown", CompOption::TypeBool)); args.push_back (CompOption ("interact_style", CompOption::TypeInt)); args.push_back (CompOption ("fast", CompOption::TypeBool)); args[0].value ().set (saveType); args[1].value ().set ((bool) shutdown); args[2].value ().set (interact_Style); args[3].value ().set ((bool) fast); screen->sessionEvent (CompSession::EventSaveYourself, args); setCloneRestartCommands (connection); setRestartStyle (connection, SmRestartImmediately); setProgramInfo (connection, getpid (), getuid ()); SmcSaveYourselfDone (connection, 1); }
bool RotateScreen::rotateWithWindow (CompAction *action, CompAction::State state, CompOption::Vector &options, int direction) { if (screen->vpSize ().width () < 2 || !direction) return false; Window xid = CompOption::getIntOptionNamed (options, "window"); if (mMoveWindow != xid) { releaseMoveWindow (); if (!mGrabIndex && !mMoving) { CompWindow *w = screen->findWindow (xid); if (w && !(w->type () & (CompWindowTypeDesktopMask | CompWindowTypeDockMask)) && !(w->state () & CompWindowStateStickyMask)) { mMoveWindow = w->id (); mMoveWindowX = w->x (); if (optionGetRaiseOnRotate ()) w->raise (); } } } if (!mGrabIndex) { CompOption::Vector o (0); o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (CompOption::getIntOptionNamed (options, "x", 0)); o[2].value ().set (CompOption::getIntOptionNamed (options, "y", 0)); initiate (NULL, 0, o); } if (mGrabIndex) { mMoving = true; mMoveTo += 360.0f / screen->vpSize ().width () * direction; mGrabbed = false; cScreen->damageScreen (); } return false; }
void PrivateScaleScreen::activateEvent (bool activating) { CompOption::Vector o (0); o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("active", CompOption::TypeBool)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (activating); screen->handleCompizEvent ("scale", "activate", o); }
TEST_F (ResizeLogicTest, DontMaximizeVerticallyIfFarFromTopEdge) { CompAction action; CompAction::State state = 0; CompOption::Vector options; options.push_back (CompOption ("window", CompOption::TypeInt)); options[0].value ().set ((int) 123); options.push_back (CompOption ("external", CompOption::TypeBool)); options[1].value ().set (true); EXPECT_CALL (mockScreen, otherGrabExist (StrEq ("resize"), _)) .WillOnce (Return (false)); EXPECT_CALL (mockScreen, pushGrab (_, StrEq ("resize"))) .WillOnce (Return ((CompScreen::GrabHandle)1)); /* hit the middle of the top edge of the window */ pointerX = mockWindowServerGeometry.centerX (); pointerY = mockWindowServerGeometry.top(); logic.initiateResizeDefaultMode(&action, state, options); /* move the pointer just a bit upwards. Still far away from the top edge of * the screen */ pointerY -= 10; XEvent event; event.type = MotionNotify; event.xmotion.root = 345; EXPECT_CALL (mockScreen, root ()) .WillRepeatedly (Return (event.xmotion.root)); logic.handleEvent(&event); EXPECT_CALL (mockScreen, removeGrab (_, _)); EXPECT_CALL (mockWindow, maximize (_)) .Times(0); logic.terminateResize(&action, state, options); }
/* Simulate a resize that is initiated by the "resize" compiz plugin himself * instead of externally. E.g.: user presses Alt + middle mouse button (the * default button assignment for resizing) * * Regression test for bug lp1045191 * https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/1045191 * This bug would cause a crash in this situation. */ TEST_F (ResizeLogicTest, DontCrashIfSourceNotExternalApp) { CompAction action; CompAction::State state = 0; CompOption::Vector options; options.push_back (CompOption ("window", CompOption::TypeInt)); options[0].value ().set ((int) 123); options.push_back (CompOption ("external", CompOption::TypeBool)); options[1].value ().set (false); /* source is not an external app */ EXPECT_CALL (mockScreen, otherGrabExist (StrEq ("resize"), _)) .WillOnce (Return (false)); EXPECT_CALL (mockScreen, pushGrab (_, StrEq ("resize"))) .WillOnce (Return ((CompScreen::GrabHandle)1)); /* hit a point near but not directly over the top window edge. * You don't have to hit the window border if the resize is * initiated by the initiate_button compiz action */ pointerX = mockWindowServerGeometry.centerX (); pointerY = mockWindowServerGeometry.top() + (mockWindowServerGeometry.height() / 4); logic.initiateResizeDefaultMode(&action, state, options); /* move the pointer to the top of the screen */ pointerY = 1; XEvent event; event.type = MotionNotify; event.xmotion.root = 345; EXPECT_CALL (mockScreen, root ()) .WillRepeatedly (Return (event.xmotion.root)); logic.handleEvent(&event); EXPECT_CALL (mockScreen, removeGrab (_, _)); logic.terminateResize(&action, state, options); }
void RotateWindow::activate () { if (window->placed () && !screen->otherGrabExist ("rotate", "switcher", "cube", NULL)) { /* reset movement */ rScreen->mMoveTo = 0.0f; int dx = window->defaultViewport ().x (); dx -= screen->vp ().x (); if (dx) { Window win; int i, x, y; unsigned int ui; CompOption::Vector o (0); XQueryPointer (screen->dpy (), screen->root (), &win, &win, &x, &y, &i, &i, &ui); if (dx * 2 > screen->vpSize ().width ()) dx -= screen->vpSize ().width (); else if (dx * 2 < -screen->vpSize ().width ()) dx += screen->vpSize ().width (); o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (x); o[2].value ().set (y); rScreen->rotate (NULL, 0, o, dx); } } window->activate (); }
bool RotateScreen::rotate (CompAction *action, CompAction::State state, CompOption::Vector &options, int direction) { if (screen->vpSize ().width () < 2 || !direction || screen->otherGrabExist ("rotate", "move", "switcher", "group-drag", "cube", NULL)) return false; if (mMoveWindow) releaseMoveWindow (); /* we allow the grab to fail here so that we can rotate on drag-and-drop */ if (!mGrabIndex) { CompOption::Vector o (0); o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (CompOption::getIntOptionNamed (options, "x", 0)); o[2].value ().set (CompOption::getIntOptionNamed (options, "y", 0)); initiate (NULL, 0, o); } mMoving = true; mMoveTo += 360.0f / screen->vpSize ().width () * direction; mGrabbed = false; cScreen->damageScreen (); return false; }
ResizeScreen::ResizeScreen (CompScreen *s) : PluginClassHandler<ResizeScreen,CompScreen> (s), gScreen (GLScreen::get (s)) { logic.mScreen = new resize::CompScreenImpl (screen); logic.cScreen = resize::CompositeScreenImpl::wrap (CompositeScreen::get (s)); logic.gScreen = resize::GLScreenImpl::wrap (gScreen); logic.options = this; CompOption::Vector atomTemplate; Display *dpy = s->dpy (); ResizeOptions::ChangeNotify notify = boost::bind (&ResizeScreen::optionChanged, this, _1, _2); atomTemplate.resize (4); for (int i = 0; i < 4; i++) { char buf[4]; snprintf (buf, 4, "%i", i); CompString tmpName (buf); atomTemplate.at (i).setName (tmpName, CompOption::TypeInt); } logic.resizeNotifyAtom = XInternAtom (s->dpy (), "_COMPIZ_RESIZE_NOTIFY", 0); logic.resizeInformationAtom = new resize::PropertyWriterImpl ( new PropertyWriter ("_COMPIZ_RESIZE_INFORMATION", atomTemplate)); for (unsigned int i = 0; i < NUM_KEYS; i++) logic.key[i] = XKeysymToKeycode (s->dpy (), XStringToKeysym (logic.rKeys[i].name)); logic.leftCursor = XCreateFontCursor (dpy, XC_left_side); logic.rightCursor = XCreateFontCursor (dpy, XC_right_side); logic.upCursor = XCreateFontCursor (dpy, XC_top_side); logic.upLeftCursor = XCreateFontCursor (dpy, XC_top_left_corner); logic.upRightCursor = XCreateFontCursor (dpy, XC_top_right_corner); logic.downCursor = XCreateFontCursor (dpy, XC_bottom_side); logic.downLeftCursor = XCreateFontCursor (dpy, XC_bottom_left_corner); logic.downRightCursor = XCreateFontCursor (dpy, XC_bottom_right_corner); logic.middleCursor = XCreateFontCursor (dpy, XC_fleur); logic.cursor[0] = logic.leftCursor; logic.cursor[1] = logic.rightCursor; logic.cursor[2] = logic.upCursor; logic.cursor[3] = logic.downCursor; optionSetInitiateKeyInitiate (resizeInitiateDefaultMode); optionSetInitiateKeyTerminate (resizeTerminate); optionSetInitiateButtonInitiate (resizeInitiateDefaultMode); optionSetInitiateButtonTerminate (resizeTerminate); optionSetOutlineModifierNotify (notify); optionSetRectangleModifierNotify (notify); optionSetStretchModifierNotify (notify); optionSetCenteredModifierNotify (notify); resizeMaskValueToKeyMask (optionGetOutlineModifierMask (), &logic.outlineMask); resizeMaskValueToKeyMask (optionGetRectangleModifierMask (), &logic.rectangleMask); resizeMaskValueToKeyMask (optionGetStretchModifierMask (), &logic.stretchMask); resizeMaskValueToKeyMask (optionGetCenteredModifierMask (), &logic.centeredMask); ScreenInterface::setHandler (s); if (gScreen) GLScreenInterface::setHandler (gScreen, false); }
void RotateScreen::handleEvent (XEvent *event) { switch (event->type) { case MotionNotify: if (screen->root () == event->xmotion.root && mGrabIndex) { if (mGrabbed) { GLfloat pointerDx = pointerX - lastPointerX; GLfloat pointerDy = pointerY - lastPointerY; // TODO: Eliminate magic numbers here if (event->xmotion.x_root < 50 || event->xmotion.y_root < 50 || event->xmotion.x_root > screen->width () - 50 || event->xmotion.y_root > screen->height () - 50) screen->warpPointer ((screen->width () / 2) - pointerX, (screen->height () / 2) - pointerY); if (optionGetInvertY ()) pointerDy = -pointerDy; mXVelocity += pointerDx * mPointerSensitivity * cubeScreen->invert (); mYVelocity += pointerDy * mPointerSensitivity; cScreen->damageScreen (); } else { mSavedPointer.setX (mSavedPointer.x () + pointerX - lastPointerX); mSavedPointer.setY (mSavedPointer.y () + pointerY - lastPointerY); } } break; case ClientMessage: if (event->xclient.message_type == Atoms::desktopViewport) { if (screen->root () == event->xclient.window) { if (screen->otherGrabExist ("rotate", "switcher", "cube", NULL)) break; /* reset movement */ mMoveTo = 0.0f; int dx = (event->xclient.data.l[0] / screen->width ()) - screen->vp ().x (); if (dx) { Window win; int i, x, y; unsigned int ui; CompOption::Vector o (0); XQueryPointer (screen->dpy (), screen->root (), &win, &win, &x, &y, &i, &i, &ui); if (dx * 2 > screen->vpSize ().width ()) dx -= screen->vpSize ().width (); else if (dx * 2 < -screen->vpSize ().width ()) dx += screen->vpSize ().width (); o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (x); o[2].value ().set (y); rotate (NULL, 0, o, dx); } } } break; default: break; } screen->handleEvent (event); }
bool RotateScreen::rotateEdgeFlip (CompAction *action, CompAction::State state, CompOption::Vector &options, int direction) { CompOption::Vector o (0); if (screen->vpSize ().width () < 2 || screen->otherGrabExist ("rotate", "move", "group-drag", NULL)) return false; if (state & CompAction::StateInitEdgeDnd) { if (!optionGetEdgeFlipDnd ()) return false; } else if (screen->otherGrabExist ("rotate", "group-drag", NULL)) { if (!optionGetEdgeFlipWindow () || !mGrabWindow || /* bail out if window is horizontally maximized, fullscreen * or sticky */ mGrabWindow->state () & (CompWindowStateMaximizedHorzMask | CompWindowStateFullscreenMask | CompWindowStateStickyMask)) return false; } else if (screen->otherGrabExist ("rotate", NULL)) { /* in that case, 'group-drag' must be the active screen grab */ if (!optionGetEdgeFlipWindow ()) return false; } else if (!optionGetEdgeFlipPointer ()) return false; o.push_back (CompOption ("root", CompOption::TypeInt)); o.push_back (CompOption ("x", CompOption::TypeInt)); o.push_back (CompOption ("y", CompOption::TypeInt)); o[0].value ().set ((int) screen->root ()); o[1].value ().set (CompOption::getIntOptionNamed (options, "x", 0)); o[2].value ().set (CompOption::getIntOptionNamed (options, "y", 0)); if (optionGetFlipTime () == 0 || (mMoving && !mSlow)) { int pointerDx = pointerX - lastPointerX; int warpX; /* TODO: Eliminate those magic numbers here */ if (direction == -1) { warpX = pointerX + screen->width (); screen->warpPointer (screen->width () - 10, 0); lastPointerX = warpX - pointerDx; rotate (NULL, 0, o, direction); XWarpPointer (screen->dpy (), None, None, 0, 0, 0, 0, -1, 0); mSavedPointer.setX (lastPointerX - 9); } else { warpX = pointerX - screen->width (); screen->warpPointer (10 - screen->width (), 0); lastPointerX = warpX - pointerDx; rotate (NULL, 0, o, direction); XWarpPointer (screen->dpy (), None, None, 0, 0, 0, 0, 1, 0); mSavedPointer.setX (lastPointerX + 9); } } else { if (!mRotateTimer.active ()) mRotateTimer.start (boost::bind (&RotateScreen::rotateFlip, this, direction), optionGetFlipTime (), (float) optionGetFlipTime () * 1.2); mMoving = true; mMoveTo += 360.0f / screen->vpSize ().width () * direction; mSlow = true; if (state & CompAction::StateInitEdge) action->setState (action->state () | CompAction::StateTermEdge); if (state & CompAction::StateInitEdgeDnd) action->setState (action->state () | CompAction::StateTermEdgeDnd); cScreen->damageScreen (); } return false; }