Merge lp:~saviq/unity-2d/unmaximize-on-drag into lp:unity-2d/3.0

Proposed by Michał Sawicz
Status: Rejected
Rejected by: Michał Sawicz
Proposed branch: lp:~saviq/unity-2d/unmaximize-on-drag
Merge into: lp:unity-2d/3.0
Diff against target: 241 lines (+117/-0)
6 files modified
panel/applets/appname/appnameapplet.cpp (+43/-0)
panel/applets/appname/appnameapplet.h (+1/-0)
panel/applets/appname/menubarwidget.cpp (+38/-0)
panel/applets/appname/menubarwidget.h (+5/-0)
panel/applets/appname/windowhelper.cpp (+28/-0)
panel/applets/appname/windowhelper.h (+2/-0)
To merge this branch: bzr merge lp:~saviq/unity-2d/unmaximize-on-drag
Reviewer Review Type Date Requested Status
Michał Sawicz Disapprove
Ugo Riboni (community) Needs Fixing
Aurélien Gâteau (community) Needs Fixing
Review via email: mp+61028@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Michał Sawicz (saviq) wrote :

Double clicking and dragging works as expected, with one exception that after dragging there seems to be a period of time during which, or a count of events, the panel doesn't receive Hover events.

I will yet try to hunt this down and will take any and all comments on why that might happen.

BTW: Hi! ;)

Revision history for this message
Aurélien Gâteau (agateau) wrote :

Hi Michał,

Thanks for your work. It works well here, but there are a few changes in the code I would like to suggest:

- The code you added to ClosedMenuBarHelper should be in MenuBarWidget: I would like ClosedMenuBarHelper to remain a small helper class to notice when a menu in the menubar is closed.

- Prefer using "const QPoint&" instead of "QPoint*" in WindowHelper::drag() and in MenuBarWidget::menuBarDragged(). Using QPoint* makes it look like the code is going to modify the point.

- Prefer using a forward declaration of QPoint class in windowhelper.h instead of #including it.

- I am worried with r564: it looks like a duplication of the code you added in MenuBarWidget. Maybe it is possible to do most of the work from MenuBarApplet?

review: Needs Fixing
Revision history for this message
Ugo Riboni (uriboni) wrote :

Hey Michal, good to see your contributions again :)
Sorry if it took a while to review this one, but UDS was in the way last week.

Functionally it works well, besides the issue you mention when dragging.
There's just one small glitch that I sometimes notice with gnome-terminal windows: they don't un-maximize to the same size they were before randomly. But i have not seen any other app do that, so it might be some other weird quirk of gnome-terminal.

May I suggest that while you try to figure out what is that is making the drag not work properly you split off the part of the patch that just takes care of the double click and submit that for review so that it can be taken in ? It's already a good improvement over not having neither doubleclick nor drag.

Some comment on code style will follow below.

Revision history for this message
Olivier Tilloy (osomon) wrote :

> Functionally it works well, besides the issue you mention when dragging.
> There's just one small glitch that I sometimes notice with gnome-terminal
> windows: they don't un-maximize to the same size they were before randomly.
> But i have not seen any other app do that, so it might be some other weird
> quirk of gnome-terminal.

This is a known issue (bug #684958), I don’t think it is related to Michał’s work.

BTW, hey Michał!

Revision history for this message
Ugo Riboni (uriboni) wrote :

124 + case QEvent::MouseButtonDblClick:
125 + QMetaObject::invokeMethod(m_widget, "menuBarDblClicked");

and

145 + QMetaObject::invokeMethod(m_widget, "menuBarDragged",
146 + Q_ARG(QPoint*, &m_dragStartPosition));

Is there any particular reason why you used invokeMethod instead of using qobject_cast<MenuBarWidget*>(m_widget) and they if the cast succeeded just call the method directly ?

review: Needs Information
Revision history for this message
Ugo Riboni (uriboni) wrote :

173 + void menuBarDblClicked();
174 + void menuBarDragged(QPoint* pos);

Please use DoubleClicked instead of DblClicked. We generally try to use non-abbreviated names in unity-2d identifiers as a rule.

review: Needs Fixing
Revision history for this message
Michał Sawicz (saviq) wrote :

> Is there any particular reason why you used invokeMethod instead of using
> qobject_cast<MenuBarWidget*>(m_widget) and they if the cast succeeded just
> call the method directly ?

I was just following what the rest of the code did. Seemed like a good way to encapsulate things, but since it's supposed to go into MenuBarWidget I might as well call it directly.

Revision history for this message
Olivier Tilloy (osomon) wrote :

> 173 + void menuBarDblClicked();
> 174 + void menuBarDragged(QPoint* pos);
>
> Please use DoubleClicked instead of DblClicked. We generally try to use non-
> abbreviated names in unity-2d identifiers as a rule.

This is consistent with the name of the event as exposed by Qt (QEvent::MouseButtonDblClick, see http://doc.qt.nokia.com/qevent.html#Type-enum).

Revision history for this message
Michał Sawicz (saviq) wrote :

> - The code you added to ClosedMenuBarHelper should be in MenuBarWidget: I
> would like ClosedMenuBarHelper to remain a small helper class to notice when a
> menu in the menubar is closed.

For some reason I didn't get the events in MenuBarWidget, but now you mentioned it they obviously should happen there. Maybe that's even the cause of the Hover events getting lost.

> - Prefer using "const QPoint&" instead of "QPoint*" in WindowHelper::drag()
> and in MenuBarWidget::menuBarDragged(). Using QPoint* makes it look like the
> code is going to modify the point.
>
> - Prefer using a forward declaration of QPoint class in windowhelper.h instead
> of #including it.

Noted.

> - I am worried with r564: it looks like a duplication of the code you added in
> MenuBarWidget. Maybe it is possible to do most of the work from MenuBarApplet?

Yes it definitely is duplication that I disliked, too. IMO there should simply be a 'QDragEvent' available that does the heavy lifting. Since the widgets alternate in visibility, what approach do you propose to get rid of that?

Revision history for this message
Michał Sawicz (saviq) wrote :

> > - The code you added to ClosedMenuBarHelper should be in MenuBarWidget: I
> > would like ClosedMenuBarHelper to remain a small helper class to notice when a
> > menu in the menubar is closed.
>
> For some reason I didn't get the events in MenuBarWidget, but now you
> mentioned it they obviously should happen there. Maybe that's even the cause
> of the Hover events getting lost.

I'm probably missing something obvious, but I'm not getting any mouse events on MenuBarWidget. MenuBarClosedHelper is installed as a filter event for MenuBarWidget, but that shouldn't prevent the latter to receive events as long as the filter doesn't return true, should it?

> > - I am worried with r564: it looks like a duplication of the code you added in
> > MenuBarWidget. Maybe it is possible to do most of the work from MenuBarApplet?
>
> Yes it definitely is duplication that I disliked, too. IMO there should simply
> be a 'QDragEvent' available that does the heavy lifting. Since the widgets
> alternate in visibility, what approach do you propose to get rid of that?

We could probably install MenuBarWidget as an event filter on AppNameApplet?

Revision history for this message
Michał Sawicz (saviq) wrote :

> May I suggest that while you try to figure out what is that is making the drag
> not work properly you split off the part of the patch that just takes care of
> the double click and submit that for review so that it can be taken in ? It's
> already a good improvement over not having neither doubleclick nor drag.

Since my approach here needs to be revised (see Aurélien's first comment), I'm gonna
keep that on hold until then, ok?

Revision history for this message
Ugo Riboni (uriboni) wrote :

> Since my approach here needs to be revised (see Aurélien's first comment), I'm
> gonna keep that on hold until then, ok?

Sounds good to me.

Revision history for this message
Aurélien Gâteau (agateau) wrote :

> > - The code you added to ClosedMenuBarHelper should be in MenuBarWidget: I
> > would like ClosedMenuBarHelper to remain a small helper class to notice when
> a
> > menu in the menubar is closed.
>
> For some reason I didn't get the events in MenuBarWidget, but now you
> mentioned it they obviously should happen there. Maybe that's even the cause
> of the Hover events getting lost.

I think it is because the MenuBarWidget eventFilter is installed as a filter on the menus rather than on the menubar itself (see MenuBarWidget::updateMenuBar()).

> > - Prefer using "const QPoint&" instead of "QPoint*" in WindowHelper::drag()
> > and in MenuBarWidget::menuBarDragged(). Using QPoint* makes it look like the
> > code is going to modify the point.
> >
> > - Prefer using a forward declaration of QPoint class in windowhelper.h
> instead
> > of #including it.
>
> Noted.
>
> > - I am worried with r564: it looks like a duplication of the code you added
> in
> > MenuBarWidget. Maybe it is possible to do most of the work from
> MenuBarApplet?
>
> Yes it definitely is duplication that I disliked, too. IMO there should simply
> be a 'QDragEvent' available that does the heavy lifting. Since the widgets
> alternate in visibility, what approach do you propose to get rid of that?

Maybe you could create a separate class which would implement the double-click and drag behavior and would be installed as an event filter on both the menu bar (the QMenuBar, not MenuBarWidget) and the panel?

Revision history for this message
Dmitry Shachnev (mitya57) wrote :

@Michał: It's not fixed yet. Can you re-base and fix your code for the current Oneiric version of Unity 2D?

Revision history for this message
Michał Sawicz (saviq) wrote :

@Dmitry I have that on my backlog, but unfortunately it's not just rebasing the code, we need to refactor it quite a bit.

Revision history for this message
Michał Sawicz (saviq) wrote :

Fix for that is coming.

review: Disapprove
Revision history for this message
Michał Sawicz (saviq) wrote :

Unmerged revisions

564. By Michał Sawicz

Also drag windows that don't have a menuBar on the panel.

563. By Michał Sawicz

Signal the window manager that the window is to be moved when titlebar
is dragged.

562. By Michał Sawicz

Unmaximize windows when their menubar is dragged down from the panel

561. By Michał Sawicz

Unmaximize windows when their menu bar is double clicked

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'panel/applets/appname/appnameapplet.cpp'
2--- panel/applets/appname/appnameapplet.cpp 2011-04-26 15:20:08 +0000
3+++ panel/applets/appname/appnameapplet.cpp 2011-05-15 16:32:32 +0000
4@@ -43,6 +43,7 @@
5 #include <QPainter>
6 #include <QApplication>
7 #include <QDesktopWidget>
8+#include <QMouseEvent>
9
10 static const char* METACITY_DIR = "/usr/share/themes/Ambiance/metacity-1";
11
12@@ -130,6 +131,8 @@
13 QLabel* m_label;
14 WindowHelper* m_windowHelper;
15 MenuBarWidget* m_menuBarWidget;
16+ QPoint m_dragStartPosition;
17+ bool m_dragInProgress;
18
19 void setupLabel()
20 {
21@@ -177,6 +180,10 @@
22 q, SLOT(updateWidgets()));
23 QObject::connect(m_menuBarWidget, SIGNAL(isEmptyChanged()),
24 q, SLOT(updateWidgets()));
25+ QObject::connect(m_menuBarWidget, SIGNAL(menuBarDblClicked()),
26+ m_windowHelper, SLOT(unmaximize()));
27+ QObject::connect(m_menuBarWidget, SIGNAL(menuBarDragged(QPoint*)),
28+ m_windowHelper, SLOT(drag(QPoint*)));
29 }
30
31 void setupKeyboardModifiersMonitor()
32@@ -274,12 +281,48 @@
33 case QEvent::HoverLeave:
34 updateWidgets();
35 break;
36+ case QEvent::MouseButtonDblClick:
37+ case QEvent::MouseButtonPress:
38+ case QEvent::MouseMove:
39+ appNameAppletMouseEvent(static_cast<QMouseEvent*>(event));
40+ break;
41 default:
42 break;
43 }
44 return false;
45 }
46
47+void AppNameApplet::appNameAppletMouseEvent(QMouseEvent* event)
48+{
49+ switch(event->type()) {
50+ case QEvent::MouseButtonDblClick:
51+ d->m_windowHelper->unmaximize();
52+ break;
53+ case QEvent::MouseButtonPress:
54+ if (event->button() == Qt::LeftButton) {
55+ d->m_dragStartPosition = event->pos();
56+ d->m_dragInProgress = true;
57+ }
58+ break;
59+ case QEvent::MouseMove:
60+ if (!d->m_dragInProgress) {
61+ break;
62+ }
63+ if (!(event->buttons() & Qt::LeftButton)) {
64+ break;
65+ }
66+ if ((event->pos() - d->m_dragStartPosition).manhattanLength()
67+ < QApplication::startDragDistance()) {
68+ break;
69+ }
70+ d->m_dragInProgress = false;
71+ d->m_windowHelper->drag(&d->m_dragStartPosition);
72+ break;
73+ default:
74+ break;
75+ }
76+}
77+
78 } // namespace
79
80 #include "appnameapplet.moc"
81
82=== modified file 'panel/applets/appname/appnameapplet.h'
83--- panel/applets/appname/appnameapplet.h 2011-01-15 01:41:03 +0000
84+++ panel/applets/appname/appnameapplet.h 2011-05-15 16:32:32 +0000
85@@ -43,6 +43,7 @@
86 protected:
87 bool event(QEvent*); // reimp
88 bool eventFilter(QObject*, QEvent*); // reimp
89+ void appNameAppletMouseEvent(QMouseEvent*);
90
91 private Q_SLOTS:
92 void updateWidgets();
93
94=== modified file 'panel/applets/appname/menubarwidget.cpp'
95--- panel/applets/appname/menubarwidget.cpp 2011-04-13 21:17:38 +0000
96+++ panel/applets/appname/menubarwidget.cpp 2011-05-15 16:32:32 +0000
97@@ -37,6 +37,7 @@
98
99 // Qt
100 #include <QActionEvent>
101+#include <QMouseEvent>
102 #include <QHBoxLayout>
103 #include <QLabel>
104 #include <QMenuBar>
105@@ -271,6 +272,11 @@
106 case QEvent::ActionChanged:
107 menuBarActionEvent(static_cast<QActionEvent*>(event));
108 break;
109+ case QEvent::MouseButtonDblClick:
110+ case QEvent::MouseButtonPress:
111+ case QEvent::MouseMove:
112+ menuBarMouseEvent(static_cast<QMouseEvent*>(event));
113+ break;
114 default:
115 break;
116 }
117@@ -322,4 +328,36 @@
118 }
119 }
120
121+void MenuBarClosedHelper::menuBarMouseEvent(QMouseEvent* event)
122+{
123+ switch (event->type()) {
124+ case QEvent::MouseButtonDblClick:
125+ QMetaObject::invokeMethod(m_widget, "menuBarDblClicked");
126+ break;
127+ case QEvent::MouseButtonPress:
128+ if (event->button() == Qt::LeftButton) {
129+ m_dragStartPosition = event->pos();
130+ m_dragInProgress = true;
131+ }
132+ break;
133+ case QEvent::MouseMove:
134+ if (!m_dragInProgress) {
135+ break;
136+ }
137+ if (!(event->buttons() & Qt::LeftButton)) {
138+ break;
139+ }
140+ if ((event->pos() - m_dragStartPosition).manhattanLength()
141+ < QApplication::startDragDistance()) {
142+ break;
143+ }
144+ m_dragInProgress = false;
145+ QMetaObject::invokeMethod(m_widget, "menuBarDragged",
146+ Q_ARG(QPoint*, &m_dragStartPosition));
147+ break;
148+ default:
149+ break;
150+ }
151+}
152+
153 #include "menubarwidget.moc"
154
155=== modified file 'panel/applets/appname/menubarwidget.h'
156--- panel/applets/appname/menubarwidget.h 2011-04-13 21:17:38 +0000
157+++ panel/applets/appname/menubarwidget.h 2011-05-15 16:32:32 +0000
158@@ -59,7 +59,10 @@
159
160 private:
161 MenuBarWidget* m_widget;
162+ QPoint m_dragStartPosition;
163+ bool m_dragInProgress;
164 void menuBarActionEvent(QActionEvent*);
165+ void menuBarMouseEvent(QMouseEvent*);
166 };
167
168 class MenuBarWidget : public QWidget
169@@ -74,6 +77,8 @@
170 Q_SIGNALS:
171 void menuBarClosed();
172 void isEmptyChanged();
173+ void menuBarDblClicked();
174+ void menuBarDragged(QPoint* pos);
175
176 protected:
177 bool eventFilter(QObject*, QEvent*); // reimp
178
179=== modified file 'panel/applets/appname/windowhelper.cpp'
180--- panel/applets/appname/windowhelper.cpp 2011-04-13 14:04:45 +0000
181+++ panel/applets/appname/windowhelper.cpp 2011-05-15 16:32:32 +0000
182@@ -43,6 +43,11 @@
183 #include <QApplication>
184 #include <QDesktopWidget>
185
186+// X11
187+#include <X11/Xlib.h>
188+#include <X11/Xatom.h>
189+#include <QX11Info>
190+
191 struct WindowHelperPrivate
192 {
193 WnckWindow* m_window;
194@@ -157,4 +162,27 @@
195 wnck_window_unmaximize(d->m_window);
196 }
197
198+void WindowHelper::drag(QPoint* pos)
199+{
200+ // this code IMO should ultimately belong to wnck
201+ if (wnck_window_is_maximized(d->m_window)) {
202+ XEvent xev;
203+ QX11Info info;
204+ Atom netMoveResize = XInternAtom(QX11Info::display(), "_NET_WM_MOVERESIZE", false);
205+ xev.xclient.type = ClientMessage;
206+ xev.xclient.message_type = netMoveResize;
207+ xev.xclient.display = QX11Info::display();
208+ xev.xclient.window = wnck_window_get_xid(d->m_window);
209+ xev.xclient.format = 32;
210+ xev.xclient.data.l[0] = pos->x();
211+ xev.xclient.data.l[1] = pos->y();
212+ xev.xclient.data.l[2] = 8; // _NET_WM_MOVERESIZE_MOVE
213+ xev.xclient.data.l[3] = Button1;
214+ xev.xclient.data.l[4] = 0;
215+ XUngrabPointer(QX11Info::display(), QX11Info::appTime());
216+ XSendEvent(QX11Info::display(), QX11Info::appRootWindow(info.screen()), false,
217+ SubstructureRedirectMask | SubstructureNotifyMask, &xev);
218+ }
219+}
220+
221 #include "windowhelper.moc"
222
223=== modified file 'panel/applets/appname/windowhelper.h'
224--- panel/applets/appname/windowhelper.h 2011-03-30 16:21:18 +0000
225+++ panel/applets/appname/windowhelper.h 2011-05-15 16:32:32 +0000
226@@ -26,6 +26,7 @@
227
228 // Qt
229 #include <QObject>
230+#include <QPoint>
231
232 struct WindowHelperPrivate;
233 class WindowHelper : public QObject
234@@ -44,6 +45,7 @@
235 void close();
236 void minimize();
237 void unmaximize();
238+ void drag(QPoint* pos);
239
240 private Q_SLOTS:
241 void update();

Subscribers

People subscribed via source and target branches