// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright (C) 2013 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Marco Trevisan
*/
#include
#include "DecorationsEdge.h"
#include "DecorationsDataPool.h"
namespace unity
{
namespace decoration
{
namespace
{
unsigned TypeToDirection(Edge::Type type)
{
switch (type)
{
case Edge::Type::TOP:
return WmMoveResizeSizeTop;
case Edge::Type::TOP_LEFT:
return WmMoveResizeSizeTopLeft;
case Edge::Type::TOP_RIGHT:
return WmMoveResizeSizeTopRight;
case Edge::Type::LEFT:
return WmMoveResizeSizeLeft;
case Edge::Type::RIGHT:
return WmMoveResizeSizeRight;
case Edge::Type::BOTTOM:
return WmMoveResizeSizeBottom;
case Edge::Type::BOTTOM_LEFT:
return WmMoveResizeSizeBottomLeft;
case Edge::Type::BOTTOM_RIGHT:
return WmMoveResizeSizeBottomRight;
case Edge::Type::GRAB:
return WmMoveResizeMove;
default:
return WmMoveResizeCancel;
}
}
}
Edge::Edge(CompWindow* win, Type t)
: win_(win)
, type_(t)
{
unsigned mask = (t == Type::GRAB) ? CompWindowActionMoveMask : CompWindowActionResizeMask;
sensitive = (win_->actions() & mask);
mouse_owner.changed.connect([this] (bool over) {
if (over)
XDefineCursor(screen->dpy(), win_->frame(), DataPool::Get()->EdgeCursor(type_));
else
XUndefineCursor(screen->dpy(), win_->frame());
});
}
Edge::Type Edge::GetType() const
{
return type_;
}
CompWindow* Edge::Window() const
{
return win_;
}
void Edge::ButtonDownEvent(CompPoint const& p, unsigned button, Time timestamp)
{
XEvent ev;
auto* dpy = screen->dpy();
ev.xclient.type = ClientMessage;
ev.xclient.display = screen->dpy();
ev.xclient.serial = 0;
ev.xclient.send_event = True;
ev.xclient.window = win_->id();
ev.xclient.message_type = Atoms::wmMoveResize;
ev.xclient.format = 32;
ev.xclient.data.l[0] = p.x();
ev.xclient.data.l[1] = p.y();
ev.xclient.data.l[2] = TypeToDirection(type_);
ev.xclient.data.l[3] = button;
ev.xclient.data.l[4] = 1;
XUngrabPointer(dpy, timestamp);
XUngrabKeyboard(dpy, timestamp);
auto mask = SubstructureRedirectMask | SubstructureNotifyMask;
XSendEvent(dpy, screen->root(), False, mask, &ev);
XSync(dpy, False);
}
std::string Edge::GetName() const
{
switch (type_)
{
case Type::TOP:
return "TopEdge";
case Type::TOP_LEFT:
return "TopLeftEdge";
case Type::TOP_RIGHT:
return "TopRightEdge";
case Type::LEFT:
return "LeftEdge";
case Type::RIGHT:
return "RightEdge";
case Type::BOTTOM:
return "BottomEdge";
case Type::BOTTOM_LEFT:
return "BottomLeftEdge";
case Type::BOTTOM_RIGHT:
return "BottomRightEdge";
case Type::GRAB:
return "GrabEdge";
default:
return "Edge";
}
}
} // decoration namespace
} // unity namespace