2 * mouse.c - mouse managing
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "layouts/floating.h"
32 #include "layouts/tile.h"
33 #include "common/xscreen.h"
35 #define MOUSEMASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
37 extern AwesomeConf globalconf
;
39 /** Move client with mouse
40 * \param screen Screen ID
42 * \ingroup ui_callback
45 uicb_client_movemouse(int screen
, char *arg
__attribute__ ((unused
)))
47 int x
, y
, ocx
, ocy
, di
, phys_screen
, newscreen
;
51 area_t area
, geometry
;
52 Client
*c
= globalconf
.focus
->client
, *target
;
53 Layout
*layout
= layout_get_current(screen
);
58 area
= screen_get_area(c
->screen
,
59 globalconf
.screens
[screen
].statusbar
,
60 &globalconf
.screens
[screen
].padding
);
62 ocx
= geometry
.x
= c
->geometry
.x
;
63 ocy
= geometry
.y
= c
->geometry
.y
;
64 phys_screen
= get_phys_screen(c
->screen
);
65 if(XGrabPointer(globalconf
.display
,
66 RootWindow(globalconf
.display
, phys_screen
),
67 False
, MOUSEMASK
, GrabModeAsync
, GrabModeAsync
,
68 RootWindow(globalconf
.display
, phys_screen
),
69 globalconf
.cursor
[CurMove
], CurrentTime
) != GrabSuccess
)
71 XQueryPointer(globalconf
.display
,
72 RootWindow(globalconf
.display
, phys_screen
),
73 &dummy
, &dummy
, &x
, &y
, &di
, &di
, &dui
);
77 XMaskEvent(globalconf
.display
, MOUSEMASK
| ExposureMask
| SubstructureRedirectMask
, &ev
);
81 XUngrabPointer(globalconf
.display
, CurrentTime
);
83 case ConfigureRequest
:
84 event_handle_configurerequest(&ev
);
87 event_handle_expose(&ev
);
90 event_handle_maprequest(&ev
);
93 event_handle_enternotify(&ev
);
96 if(c
->isfloating
|| layout
->arrange
== layout_floating
)
98 geometry
.x
= ocx
+ (ev
.xmotion
.x
- x
);
99 geometry
.y
= ocy
+ (ev
.xmotion
.y
- y
);
100 if(abs(geometry
.x
) < globalconf
.screens
[screen
].snap
+ area
.x
&& geometry
.x
> area
.x
)
102 else if(abs((area
.x
+ area
.width
) - (geometry
.x
+ c
->geometry
.width
+ 2 * c
->border
))
103 < globalconf
.screens
[screen
].snap
)
104 geometry
.x
= area
.x
+ area
.width
- c
->geometry
.width
- 2 * c
->border
;
105 if(abs(geometry
.y
) < globalconf
.screens
[screen
].snap
+ area
.y
&& geometry
.y
> area
.y
)
107 else if(abs((area
.y
+ area
.height
) - (geometry
.y
+ c
->geometry
.height
+ 2 * c
->border
))
108 < globalconf
.screens
[screen
].snap
)
109 geometry
.y
= area
.y
+ area
.height
- c
->geometry
.height
- 2 * c
->border
;
110 geometry
.width
= c
->geometry
.width
;
111 geometry
.height
= c
->geometry
.height
;
112 client_resize(c
, geometry
);
113 while(XCheckMaskEvent(globalconf
.display
, PointerMotionMask
, &ev
));
117 XQueryPointer(globalconf
.display
,
118 RootWindow(globalconf
.display
, phys_screen
),
119 &dummy
, &child
, &x
, &y
, &di
, &di
, &dui
);
120 if((newscreen
= screen_get_bycoord(globalconf
.screens_info
, c
->screen
, x
, y
)) != c
->screen
)
122 move_client_to_screen(c
, newscreen
, True
);
123 globalconf
.screens
[c
->screen
].need_arrange
= True
;
124 globalconf
.screens
[newscreen
].need_arrange
= True
;
127 if((target
= client_get_bywin(globalconf
.clients
, child
))
128 && target
!= c
&& !target
->isfloating
)
130 client_list_swap(&globalconf
.clients
, c
, target
);
131 globalconf
.screens
[c
->screen
].need_arrange
= True
;
140 /** Resize client with mouse
141 * \param screen Screen ID
143 * \ingroup ui_callback
146 uicb_client_resizemouse(int screen
, char *arg
__attribute__ ((unused
)))
148 int ocx
= 0, ocy
= 0, n
;
150 Client
*c
= globalconf
.focus
->client
;
151 Tag
**curtags
= tags_get_current(screen
);
152 Layout
*layout
= curtags
[0]->layout
;
153 area_t area
= { 0, 0, 0, 0, NULL
, NULL
}, geometry
;
156 /* only handle floating and tiled layouts */
159 if(layout
->arrange
== layout_floating
|| c
->isfloating
)
165 else if (layout
->arrange
== layout_tile
|| layout
->arrange
== layout_tileleft
166 || layout
->arrange
== layout_tilebottom
|| layout
->arrange
== layout_tiletop
)
168 for(n
= 0, c
= globalconf
.clients
; c
; c
= c
->next
)
169 if(IS_TILED(c
, screen
))
172 if(n
<= curtags
[0]->nmaster
) return;
174 for(c
= globalconf
.clients
; c
&& !IS_TILED(c
, screen
); c
= c
->next
);
177 area
= screen_get_area(screen
,
178 globalconf
.screens
[c
->screen
].statusbar
,
179 &globalconf
.screens
[c
->screen
].padding
);
185 if(XGrabPointer(globalconf
.display
, RootWindow(globalconf
.display
,
186 get_phys_screen(c
->screen
)),
187 False
, MOUSEMASK
, GrabModeAsync
, GrabModeAsync
,
188 RootWindow(globalconf
.display
,get_phys_screen(c
->screen
)),
189 globalconf
.cursor
[CurResize
], CurrentTime
) != GrabSuccess
)
192 if(curtags
[0]->layout
->arrange
== layout_tileleft
)
193 XWarpPointer(globalconf
.display
, None
, c
->win
, 0, 0, 0, 0, 0, c
->geometry
.height
+ c
->border
- 1);
194 else if(curtags
[0]->layout
->arrange
== layout_tilebottom
)
195 XWarpPointer(globalconf
.display
, None
, c
->win
, 0, 0, 0, 0, c
->geometry
.width
+ c
->border
- 1, c
->geometry
.height
+ c
->border
- 1);
196 else if(curtags
[0]->layout
->arrange
== layout_tiletop
)
197 XWarpPointer(globalconf
.display
, None
, c
->win
, 0, 0, 0, 0, c
->geometry
.width
+ c
->border
- 1, 0);
199 XWarpPointer(globalconf
.display
, None
, c
->win
, 0, 0, 0, 0, c
->geometry
.width
+ c
->border
- 1, c
->geometry
.height
+ c
->border
- 1);
203 XMaskEvent(globalconf
.display
, MOUSEMASK
| ExposureMask
| SubstructureRedirectMask
, &ev
);
207 XUngrabPointer(globalconf
.display
, CurrentTime
);
209 case ConfigureRequest
:
210 event_handle_configurerequest(&ev
);
213 event_handle_expose(&ev
);
216 event_handle_maprequest(&ev
);
219 if(layout
->arrange
== layout_floating
|| c
->isfloating
)
221 if((geometry
.width
= ev
.xmotion
.x
- ocx
- 2 * c
->border
+ 1) <= 0)
223 if((geometry
.height
= ev
.xmotion
.y
- ocy
- 2 * c
->border
+ 1) <= 0)
225 geometry
.x
= c
->geometry
.x
;
226 geometry
.y
= c
->geometry
.y
;
227 client_resize(c
, client_geometry_hints(c
, geometry
));
229 else if(layout
->arrange
== layout_tile
|| layout
->arrange
== layout_tileleft
230 || layout
->arrange
== layout_tiletop
|| layout
->arrange
== layout_tilebottom
)
232 if(layout
->arrange
== layout_tile
)
233 mwfact
= (double) (ev
.xmotion
.x
- area
.x
) / area
.width
;
234 else if(curtags
[0]->layout
->arrange
== layout_tileleft
)
235 mwfact
= 1 - (double) (ev
.xmotion
.x
- area
.x
) / area
.width
;
236 else if(curtags
[0]->layout
->arrange
== layout_tilebottom
)
237 mwfact
= (double) (ev
.xmotion
.y
- area
.y
) / area
.height
;
239 mwfact
= 1 - (double) (ev
.xmotion
.y
- area
.y
) / area
.height
;
240 if(mwfact
< 0.1) mwfact
= 0.1;
241 else if(mwfact
> 0.9) mwfact
= 0.9;
242 if(fabs(curtags
[0]->mwfact
- mwfact
) >= 0.01)
244 curtags
[0]->mwfact
= mwfact
;
245 globalconf
.screens
[screen
].need_arrange
= True
;
247 while(XCheckMaskEvent(globalconf
.display
, PointerMotionMask
, &ev
));
257 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80