Round the the window move target positions, this should fix jumping windows.

Coding style.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38789 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2010-09-22 22:27:31 +00:00
parent 9503cf19be
commit a2336b86cc
6 changed files with 261 additions and 242 deletions
@@ -6,6 +6,7 @@
* Clemens Zeidler <[email protected]> * Clemens Zeidler <[email protected]>
*/ */
#include "SATGroup.h" #include "SATGroup.h"
#include <Debug.h> #include <Debug.h>
+133 -123
View File
@@ -8,6 +8,7 @@
#ifndef SAT_GROUP_H #ifndef SAT_GROUP_H
#define SAT_GROUP_H #define SAT_GROUP_H
#include <Rect.h> #include <Rect.h>
#include "ObjectList.h" #include "ObjectList.h"
@@ -50,21 +51,22 @@ public:
class Crossing : public BReferenceable { class Crossing : public BReferenceable {
public: public:
Crossing(Tab* vertical, Tab* horizontal); Crossing(Tab* vertical, Tab* horizontal);
~Crossing(); ~Crossing();
Corner* GetCorner(Corner::position_t corner) const; Corner* GetCorner(Corner::position_t corner) const;
Corner* GetOppositeCorner(Corner::position_t corner) const; Corner* GetOppositeCorner(
Corner::position_t corner) const;
Corner* LeftTopCorner() { return &fLeftTop; } Corner* LeftTopCorner() { return &fLeftTop; }
Corner* RightTopCorner() { return &fRightTop; } Corner* RightTopCorner() { return &fRightTop; }
Corner* LeftBottomCorner() { return &fLeftBottom; } Corner* LeftBottomCorner() { return &fLeftBottom; }
Corner* RightBottomCorner() { return &fRightBottom; } Corner* RightBottomCorner() { return &fRightBottom; }
Tab* VerticalTab() const; Tab* VerticalTab() const;
Tab* HorizontalTab() const; Tab* HorizontalTab() const;
void Trace() const; void Trace() const;
private: private:
Corner* _GetCorner(Corner::position_t corner) const; Corner* _GetCorner(Corner::position_t corner) const;
@@ -92,34 +94,35 @@ public:
kHorizontal kHorizontal
}; };
Tab(SATGroup* group, Variable* variable, Tab(SATGroup* group, Variable* variable,
orientation_t orientation); orientation_t orientation);
~Tab(); ~Tab();
float Position() const; float Position() const;
void SetPosition(float position); void SetPosition(float position);
orientation_t Orientation() const; orientation_t Orientation() const;
//! Caller takes ownership of the constraint. //! Caller takes ownership of the constraint.
Constraint* Connect(Variable* variable); Constraint* Connect(Variable* variable);
BReference<Crossing> AddCrossing(Tab* tab); BReference<Crossing> AddCrossing(Tab* tab);
bool RemoveCrossing(Crossing* crossing); bool RemoveCrossing(Crossing* crossing);
int32 FindCrossingIndex(Tab* tab); int32 FindCrossingIndex(Tab* tab);
int32 FindCrossingIndex(float tabPosition); int32 FindCrossingIndex(float tabPosition);
Crossing* FindCrossing(Tab* tab); Crossing* FindCrossing(Tab* tab);
Crossing* FindCrossing(float tabPosition); Crossing* FindCrossing(float tabPosition);
const CrossingList* GetCrossingList() const; const CrossingList* GetCrossingList() const;
static int CompareFunction(const Tab* tab1, const Tab* tab2); static int CompareFunction(const Tab* tab1,
const Tab* tab2);
private: private:
SATGroup* fGroup; SATGroup* fGroup;
Variable* fVariable; Variable* fVariable;
orientation_t fOrientation; orientation_t fOrientation;
CrossingList fCrossingList; CrossingList fCrossingList;
}; };
@@ -130,66 +133,67 @@ public:
Crossing* rightBottom); Crossing* rightBottom);
~WindowArea(); ~WindowArea();
bool SetGroup(SATGroup* group); bool SetGroup(SATGroup* group);
const SATWindowList& WindowList() { return fWindowList; } const SATWindowList& WindowList() { return fWindowList; }
const SATWindowList& LayerOrder() { return fWindowLayerOrder; } const SATWindowList& LayerOrder() { return fWindowLayerOrder; }
bool MoveWindowToPosition(SATWindow* window, bool MoveWindowToPosition(SATWindow* window,
int32 index); int32 index);
void UpdateSizeLimits(); void UpdateSizeLimits();
Crossing* LeftTopCrossing() Crossing* LeftTopCrossing()
{ return fLeftTopCrossing.Get(); } { return fLeftTopCrossing.Get(); }
Crossing* RightTopCrossing() Crossing* RightTopCrossing()
{ return fRightTopCrossing.Get(); } { return fRightTopCrossing.Get(); }
Crossing* LeftBottomCrossing() Crossing* LeftBottomCrossing()
{ return fLeftBottomCrossing.Get(); } { return fLeftBottomCrossing.Get(); }
Crossing* RightBottomCrossing() Crossing* RightBottomCrossing()
{ return fRightBottomCrossing.Get(); } { return fRightBottomCrossing.Get(); }
Tab* LeftTab(); Tab* LeftTab();
Tab* RightTab(); Tab* RightTab();
Tab* TopTab(); Tab* TopTab();
Tab* BottomTab(); Tab* BottomTab();
BRect Frame(); BRect Frame();
bool PropagateToGroup(SATGroup* group); bool PropagateToGroup(SATGroup* group);
bool MoveToTopLayer(SATWindow* window); bool MoveToTopLayer(SATWindow* window);
private: private:
friend class SATGroup; friend class SATGroup;
/*! SATGroup adds new windows to the area. */ /*! SATGroup adds new windows to the area. */
bool _AddWindow(SATWindow* window, bool _AddWindow(SATWindow* window,
SATWindow* after = NULL); SATWindow* after = NULL);
/*! After the last window has been removed the WindowArea delete himself /*! After the last window has been removed the WindowArea delete
and clean up all crossings. */ himself and clean up all crossings. */
bool _RemoveWindow(SATWindow* window); bool _RemoveWindow(SATWindow* window);
inline void _InitCorners(); inline void _InitCorners();
inline void _CleanupCorners(); inline void _CleanupCorners();
inline void _SetToWindowCorner(Corner* corner); inline void _SetToWindowCorner(Corner* corner);
inline void _SetToNeighbourCorner(Corner* neighbour); inline void _SetToNeighbourCorner(Corner* neighbour);
inline void _UnsetWindowCorner(Corner* corner); inline void _UnsetWindowCorner(Corner* corner);
//! opponent is the other neighbour of the neighbour //! opponent is the other neighbour of the neighbour
inline void _UnsetNeighbourCorner(Corner* neighbour, inline void _UnsetNeighbourCorner(Corner* neighbour,
Corner* opponent); Corner* opponent);
// Find crossing by tab position in group and if not exist create it. // Find crossing by tab position in group and if not exist create
BReference<Crossing> _CrossingByPosition(Crossing* crossing, // it.
SATGroup* group); BReference<Crossing> _CrossingByPosition(Crossing* crossing,
SATGroup* group);
SATGroup* fGroup; SATGroup* fGroup;
SATWindowList fWindowList; SATWindowList fWindowList;
SATWindowList fWindowLayerOrder; SATWindowList fWindowLayerOrder;
BReference<Crossing> fLeftTopCrossing; BReference<Crossing> fLeftTopCrossing;
BReference<Crossing> fRightTopCrossing; BReference<Crossing> fRightTopCrossing;
BReference<Crossing> fLeftBottomCrossing; BReference<Crossing> fLeftBottomCrossing;
BReference<Crossing> fRightBottomCrossing; BReference<Crossing> fRightBottomCrossing;
}; };
@@ -203,77 +207,83 @@ public:
friend class WindowArea; friend class WindowArea;
friend class GroupCookie; friend class GroupCookie;
SATGroup(); SATGroup();
~SATGroup(); ~SATGroup();
LinearSpec* GetLinearSpec() { return &fLinearSpec; } LinearSpec* GetLinearSpec() { return &fLinearSpec; }
void AdjustWindows(SATWindow* triggerWindow); void AdjustWindows(SATWindow* triggerWindow);
/*! Create a new WindowArea from the crossing and add the window. */ /*! Create a new WindowArea from the crossing and add the window. */
bool AddWindow(SATWindow* window, Tab* left, Tab* top, bool AddWindow(SATWindow* window, Tab* left, Tab* top,
Tab* right, Tab* bottom); Tab* right, Tab* bottom);
/*! Add a window to an existing window area. */ /*! Add a window to an existing window area. */
bool AddWindow(SATWindow* window, WindowArea* area, bool AddWindow(SATWindow* window, WindowArea* area,
SATWindow* after = NULL); SATWindow* after = NULL);
bool RemoveWindow(SATWindow* window); bool RemoveWindow(SATWindow* window);
int32 CountItems(); int32 CountItems();
SATWindow* WindowAt(int32 index); SATWindow* WindowAt(int32 index);
const WindowAreaList& GetAreaList() { return fWindowAreaList; } const WindowAreaList& GetAreaList() { return fWindowAreaList; }
/*! \return a sorted tab list. */ /*! \return a sorted tab list. */
const TabList* HorizontalTabs(); const TabList* HorizontalTabs();
const TabList* VerticalTabs(); const TabList* VerticalTabs();
Tab* FindHorizontalTab(float position); Tab* FindHorizontalTab(float position);
Tab* FindVerticalTab(float position); Tab* FindVerticalTab(float position);
private: private:
BReference<Tab> _AddHorizontalTab(float position = 0); BReference<Tab> _AddHorizontalTab(float position = 0);
BReference<Tab> _AddVerticalTab(float position = 0); BReference<Tab> _AddVerticalTab(float position = 0);
bool _RemoveHorizontalTab(Tab* tab); bool _RemoveHorizontalTab(Tab* tab);
bool _RemoveVerticalTab(Tab* tab); bool _RemoveVerticalTab(Tab* tab);
Tab* _FindTab(const TabList& list, float position); Tab* _FindTab(const TabList& list, float position);
void _SplitGroupIfNecessary(SATWindow* removedWindow); void _SplitGroupIfNecessary(
void _FillNeighbourList(WindowAreaList& neighbourWindows, SATWindow* removedWindow);
WindowArea* area); void _FillNeighbourList(
void _LeftNeighbours(WindowAreaList& neighbourWindows, WindowAreaList& neighbourWindows,
WindowArea* window); WindowArea* area);
void _TopNeighbours(WindowAreaList& neighbourWindows, void _LeftNeighbours(
WindowArea* window); WindowAreaList& neighbourWindows,
void _RightNeighbours(WindowAreaList& neighbourWindows, WindowArea* window);
WindowArea* window); void _TopNeighbours(
void _BottomNeighbours(WindowAreaList& neighbourWindows, WindowAreaList& neighbourWindows,
WindowArea* window); WindowArea* window);
bool _FindConnectedGroup(WindowAreaList& seedList, void _RightNeighbours(
SATWindow* removedWindow, WindowAreaList& neighbourWindows,
WindowAreaList& newGroup); WindowArea* window);
void _FollowSeed(WindowArea* area, WindowArea* veto, void _BottomNeighbours(
WindowAreaList& seedList, WindowAreaList& neighbourWindows,
WindowAreaList& newGroup); WindowArea* window);
void _SpawnNewGroup(const WindowAreaList& newGroup); bool _FindConnectedGroup(WindowAreaList& seedList,
SATWindow* removedWindow,
WindowAreaList& newGroup);
void _FollowSeed(WindowArea* area, WindowArea* veto,
WindowAreaList& seedList,
WindowAreaList& newGroup);
void _SpawnNewGroup(const WindowAreaList& newGroup);
void _EnsureGroupIsOnScreen(SATGroup* group); void _EnsureGroupIsOnScreen(SATGroup* group);
inline void _CallculateXOffset(BPoint& offset, BRect& frame, inline void _CallculateXOffset(BPoint& offset, BRect& frame,
BRect& screen); BRect& screen);
inline void _CallculateYOffset(BPoint& offset, BRect& frame, inline void _CallculateYOffset(BPoint& offset, BRect& frame,
BRect& screen); BRect& screen);
protected: protected:
WindowAreaList fWindowAreaList; WindowAreaList fWindowAreaList;
SATWindowList fSATWindowList; SATWindowList fSATWindowList;
LinearSpec fLinearSpec; LinearSpec fLinearSpec;
private: private:
TabList fHorizontalTabs; TabList fHorizontalTabs;
bool fHorizontalTabsSorted; bool fHorizontalTabsSorted;
TabList fVerticalTabs; TabList fVerticalTabs;
bool fVerticalTabsSorted; bool fVerticalTabsSorted;
}; };
@@ -6,6 +6,7 @@
* Clemens Zeidler <[email protected]> * Clemens Zeidler <[email protected]>
*/ */
#include "SATWindow.h" #include "SATWindow.h"
#include <Debug.h> #include <Debug.h>
@@ -118,14 +119,14 @@ GroupCookie::MoveWindow(int32 workspace)
Desktop* desktop = window->Desktop(); Desktop* desktop = window->Desktop();
BRect frame = fSATWindow->CompleteWindowFrame(); BRect frame = fSATWindow->CompleteWindowFrame();
desktop->MoveWindowBy(window, fLeftBorder->Value() - frame.left, desktop->MoveWindowBy(window, round(fLeftBorder->Value() - frame.left),
fTopBorder->Value() - frame.top, workspace); round(fTopBorder->Value() - frame.top), workspace);
// Update frame to the new position // Update frame to the new position
frame.OffsetBy(fLeftBorder->Value() - frame.left, frame.OffsetBy(round(fLeftBorder->Value() - frame.left),
fTopBorder->Value() - frame.top); round(fTopBorder->Value() - frame.top));
desktop->ResizeWindowBy(window, fRightBorder->Value() - frame.right, desktop->ResizeWindowBy(window, round(fRightBorder->Value() - frame.right),
fBottomBorder->Value() - frame.bottom); round(fBottomBorder->Value() - frame.bottom));
_UpdateWindowSize(frame); _UpdateWindowSize(frame);
} }
+88 -86
View File
@@ -24,129 +24,131 @@ class Window;
class GroupCookie class GroupCookie
{ {
public: public:
GroupCookie(SATWindow* satWindow); GroupCookie(SATWindow* satWindow);
~GroupCookie(); ~GroupCookie();
bool Init(SATGroup* group, WindowArea* area); bool Init(SATGroup* group, WindowArea* area);
void Uninit(); void Uninit();
void DoGroupLayout(SATWindow* triggerWindow); void DoGroupLayout(SATWindow* triggerWindow);
void MoveWindow(int32 workspace); void MoveWindow(int32 workspace);
void SetSizeLimits(int32 minWidth, int32 maxWidth, void SetSizeLimits(int32 minWidth, int32 maxWidth,
int32 minHeight, int32 maxHeight); int32 minHeight, int32 maxHeight);
SATGroup* GetGroup() { return fSATGroup.Get(); } SATGroup* GetGroup() { return fSATGroup.Get(); }
WindowArea* GetWindowArea() { return fWindowArea; } WindowArea* GetWindowArea() { return fWindowArea; }
bool PropagateToGroup(SATGroup* group, WindowArea* area); bool PropagateToGroup(SATGroup* group,
WindowArea* area);
private: private:
void _UpdateWindowSize(const BRect& frame); void _UpdateWindowSize(const BRect& frame);
SATWindow* fSATWindow; SATWindow* fSATWindow;
BReference<SATGroup> fSATGroup; BReference<SATGroup> fSATGroup;
WindowArea* fWindowArea; WindowArea* fWindowArea;
Variable* fLeftBorder; Variable* fLeftBorder;
Variable* fTopBorder; Variable* fTopBorder;
Variable* fRightBorder; Variable* fRightBorder;
Variable* fBottomBorder; Variable* fBottomBorder;
Constraint* fLeftBorderConstraint; Constraint* fLeftBorderConstraint;
Constraint* fTopBorderConstraint; Constraint* fTopBorderConstraint;
Constraint* fRightBorderConstraint; Constraint* fRightBorderConstraint;
Constraint* fBottomBorderConstraint; Constraint* fBottomBorderConstraint;
Constraint* fLeftConstraint; Constraint* fLeftConstraint;
Constraint* fTopConstraint; Constraint* fTopConstraint;
Constraint* fMinWidthConstraint; Constraint* fMinWidthConstraint;
Constraint* fMinHeightConstraint; Constraint* fMinHeightConstraint;
Constraint* fMaxWidthConstraint; Constraint* fMaxWidthConstraint;
Constraint* fMaxHeightConstraint; Constraint* fMaxHeightConstraint;
Constraint* fWidthConstraint; Constraint* fWidthConstraint;
Constraint* fHeightConstraint; Constraint* fHeightConstraint;
}; };
class SATWindow { class SATWindow {
public: public:
SATWindow(StackAndTile* sat, Window* window); SATWindow(StackAndTile* sat, Window* window);
~SATWindow(); ~SATWindow();
Window* GetWindow() { return fWindow; } Window* GetWindow() { return fWindow; }
SATDecorator* GetDecorator(); SATDecorator* GetDecorator();
StackAndTile* GetStackAndTile() { return fStackAndTile; } StackAndTile* GetStackAndTile() { return fStackAndTile; }
Desktop* GetDesktop() { return fDesktop; } Desktop* GetDesktop() { return fDesktop; }
//! Can be NULL if memory allocation failed! //! Can be NULL if memory allocation failed!
SATGroup* GetGroup(); SATGroup* GetGroup();
WindowArea* GetWindowArea() { WindowArea* GetWindowArea() {
return fGroupCookie->GetWindowArea(); } return fGroupCookie->GetWindowArea(); }
bool HandleMessage(SATWindow* sender, bool HandleMessage(SATWindow* sender,
BPrivate::ServerLink& link); BPrivate::ServerLink& link);
bool PropagateToGroup(SATGroup* group, WindowArea* area); bool PropagateToGroup(SATGroup* group,
WindowArea* area);
//! Move the window to the tab's position. //! Move the window to the tab's position.
void MoveWindowToSAT(int32 workspace); void MoveWindowToSAT(int32 workspace);
// hook function called from SATGroup // hook function called from SATGroup
bool AddedToGroup(SATGroup* group, WindowArea* area); bool AddedToGroup(SATGroup* group, WindowArea* area);
bool RemovedFromGroup(SATGroup* group); bool RemovedFromGroup(SATGroup* group);
void RemovedFromArea(WindowArea* area); void RemovedFromArea(WindowArea* area);
bool StackWindow(SATWindow* child); bool StackWindow(SATWindow* child);
void FindSnappingCandidates(); void FindSnappingCandidates();
bool JoinCandidates(); bool JoinCandidates();
void DoWindowLayout(); void DoWindowLayout();
void DoGroupLayout(); void DoGroupLayout();
void SetSizeLimits(int32 minWidth, int32 maxWidth, void SetSizeLimits(int32 minWidth, int32 maxWidth,
int32 minHeight, int32 maxHeight); int32 minHeight, int32 maxHeight);
//! \return the complete window frame including the Decorator //! \return the complete window frame including the Decorator
BRect CompleteWindowFrame(); BRect CompleteWindowFrame();
void GetSizeLimits(int32* minWidth, int32* maxWidth, void GetSizeLimits(int32* minWidth, int32* maxWidth,
int32* minHeight, int32* maxHeight) const; int32* minHeight, int32* maxHeight) const;
//! \return true if window is in a group with a least another window //! \return true if window is in a group with a least another window
bool PositionManagedBySAT(); bool PositionManagedBySAT();
bool HighlightTab(bool active); bool HighlightTab(bool active);
bool HighlightBorders(bool active); bool HighlightBorders(bool active);
bool IsTabHighlighted(); bool IsTabHighlighted();
bool IsBordersHighlighted(); bool IsBordersHighlighted();
bool SetStackedMode(bool stacked = true); bool SetStackedMode(bool stacked = true);
bool SetStackedTabLength(float length); bool SetStackedTabLength(float length);
bool SetStackedTabMoving(bool moving = true); bool SetStackedTabMoving(bool moving = true);
void TabLocationMoved(float location, bool shifting); void TabLocationMoved(float location, bool shifting);
private: private:
void _InitGroup(); void _InitGroup();
Window* fWindow; Window* fWindow;
StackAndTile* fStackAndTile; StackAndTile* fStackAndTile;
Desktop* fDesktop; Desktop* fDesktop;
//! Current group. //! Current group.
GroupCookie* fGroupCookie; GroupCookie* fGroupCookie;
/*! If the window is added to another group the own group is cached /*! If the window is added to another group the own group is cached
here. */ here. */
GroupCookie fOwnGroupCookie; GroupCookie fOwnGroupCookie;
GroupCookie fForeignGroupCookie; GroupCookie fForeignGroupCookie;
SATSnappingBehaviour* fOngoingSnapping; SATSnappingBehaviour* fOngoingSnapping;
SATStacking fSATStacking; SATStacking fSATStacking;
SATTiling fSATTiling; SATTiling fSATTiling;
SATSnappingBehaviourList fSATSnappingBehaviourList; SATSnappingBehaviourList fSATSnappingBehaviourList;
bool fShutdown; bool fShutdown;
}; };
@@ -6,6 +6,7 @@
* Clemens Zeidler <haiku@clemens-zeidler.de> * Clemens Zeidler <haiku@clemens-zeidler.de>
*/ */
#include "StackAndTile.h" #include "StackAndTile.h"
#include <Debug.h> #include <Debug.h>
@@ -8,6 +8,7 @@
#ifndef STACK_AND_TILE_H #ifndef STACK_AND_TILE_H
#define STACK_AND_TILE_H #define STACK_AND_TILE_H
#include <map> #include <map>
#include <Message.h> #include <Message.h>
@@ -107,60 +108,63 @@ private:
class GroupIterator { class GroupIterator {
public: public:
GroupIterator(StackAndTile* sat, Desktop* desktop); GroupIterator(StackAndTile* sat,
Desktop* desktop);
void RewindToFront(); void RewindToFront();
SATGroup* NextGroup(); SATGroup* NextGroup();
private: private:
StackAndTile* fStackAndTile; StackAndTile* fStackAndTile;
Desktop* fDesktop; Desktop* fDesktop;
Window* fCurrentWindow; Window* fCurrentWindow;
SATGroup* fCurrentGroup; SATGroup* fCurrentGroup;
}; };
class WindowIterator { class WindowIterator {
public: public:
WindowIterator(SATGroup* group, WindowIterator(SATGroup* group,
bool reverseLayerOrder = false); bool reverseLayerOrder = false);
void Rewind(); void Rewind();
/*! Iterates over all areas in the group and return the windows in the /*! Iterates over all areas in the group and return the windows in
areas. Within one area the windows are ordered by their layer position. the areas. Within one area the windows are ordered by their layer
If reverseLayerOrder is false the bottommost window comes first. */ position. If reverseLayerOrder is false the bottommost window comes
SATWindow* NextWindow(); first. */
SATWindow* NextWindow();
private: private:
SATWindow* _ReverseNextWindow(); SATWindow* _ReverseNextWindow();
void _ReverseRewind(); void _ReverseRewind();
SATGroup* fGroup; SATGroup* fGroup;
bool fReverseLayerOrder; bool fReverseLayerOrder;
WindowArea* fCurrentArea; WindowArea* fCurrentArea;
int32 fAreaIndex; int32 fAreaIndex;
int32 fWindowIndex; int32 fWindowIndex;
}; };
class SATSnappingBehaviour { class SATSnappingBehaviour {
public: public:
virtual ~SATSnappingBehaviour(); virtual ~SATSnappingBehaviour();
/*! Find all window candidates which possibly can join the group. Found /*! Find all window candidates which possibly can join the group. Found
candidates are marked here visual. */ candidates are marked here visual. */
virtual bool FindSnappingCandidates(SATGroup* group) = 0; virtual bool FindSnappingCandidates(SATGroup* group) = 0;
/*! Join all candidates found in FindSnappingCandidates to the group. /*! Join all candidates found in FindSnappingCandidates to the group.
Previously visually mark should be removed here. \return true if Previously visually mark should be removed here. \return true if
integration has been succeed. */ integration has been succeed. */
virtual bool JoinCandidates() = 0; virtual bool JoinCandidates() = 0;
/*! Update the window tab values, solve the layout and move all windows in /*! Update the window tab values, solve the layout and move all windows in
the group accordantly. */ the group accordantly. */
virtual void DoWindowLayout() = 0; virtual void DoWindowLayout() = 0;
virtual void RemovedFromArea(WindowArea* area) {} virtual void RemovedFromArea(WindowArea* area) {}
virtual void TabLocationMoved(float location, bool shifting) {} virtual void TabLocationMoved(float location, bool shifting)
{}
}; };