]> icculus.org git repositories - dana/openbox.git/blob - openbox/moveresize.c
move the move/resize functionality into moveresize.c, for use with the netwm atoms...
[dana/openbox.git] / openbox / moveresize.c
1 #include "grab.h"
2 #include "framerender.h"
3 #include "prop.h"
4 #include "client.h"
5 #include "dispatch.h"
6 #include "openbox.h"
7
8 #include <X11/Xlib.h>
9 #include <glib.h>
10
11 gboolean moveresize_in_progress = FALSE;
12 static gboolean moving = FALSE; /* TRUE - moving, FALSE - resizing */
13
14 static Window coords = None;
15 static int start_x, start_y, start_cx, start_cy, start_cw, start_ch;
16 static int cur_x, cur_y;
17 static Client *client;
18 static guint button;
19 static guint32 corner;
20 static Corner lockcorner;
21
22 #define POPUP_X (10)
23 #define POPUP_Y (10)
24
25 static void popup_coords(char *format, int a, int b)
26 {
27     XSetWindowAttributes attrib;
28     Size s;
29     char *text;
30
31     if (coords == None) {
32         attrib.override_redirect = TRUE;
33         coords = XCreateWindow(ob_display, ob_root,
34                                0, 0, 1, 1, 0, render_depth, InputOutput,
35                                render_visual, CWOverrideRedirect, &attrib);
36         g_assert(coords != None);
37
38         XMapWindow(ob_display, coords);
39     }
40
41     text = g_strdup_printf(format, a, b);
42     framerender_size_popup_label(text, &s);
43     XMoveResizeWindow(ob_display, coords,
44                       POPUP_X, POPUP_Y, s.width, s.height);
45     framerender_popup_label(coords, &s, text);
46     g_free(text);
47 }
48
49 void moveresize_start(Client *c, int x, int y, guint b, guint32 cnr)
50 {
51     Cursor cur;
52
53     g_assert(!moveresize_in_progress);
54
55     client = c;
56     start_cx = c->frame->area.x;
57     start_cy = c->frame->area.y;
58     start_cw = c->area.width;
59     start_ch = c->area.height;
60     start_x = x;
61     start_y = y;
62     button = b;
63     corner = cnr;
64
65     moveresize_in_progress = TRUE;
66     moving = (corner == prop_atoms.net_wm_moveresize_move ||
67               corner == prop_atoms.net_wm_moveresize_move_keyboard);
68
69     if (corner == prop_atoms.net_wm_moveresize_size_topleft)
70         cur = ob_cursors.tl;
71     else if (corner == prop_atoms.net_wm_moveresize_size_top)
72         cur = ob_cursors.tl;
73     else if (corner == prop_atoms.net_wm_moveresize_size_topright)
74         cur = ob_cursors.tr;
75     else if (corner == prop_atoms.net_wm_moveresize_size_right)
76         cur = ob_cursors.tr;
77     else if (corner == prop_atoms.net_wm_moveresize_size_bottomright)
78         cur = ob_cursors.br;
79     else if (corner == prop_atoms.net_wm_moveresize_size_bottom)
80         cur = ob_cursors.br;
81     else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft)
82         cur = ob_cursors.bl;
83     else if (corner == prop_atoms.net_wm_moveresize_size_left)
84         cur = ob_cursors.bl;
85     else if (corner == prop_atoms.net_wm_moveresize_size_keyboard)
86         cur = ob_cursors.br;
87     else if (corner == prop_atoms.net_wm_moveresize_move)
88         cur = ob_cursors.move;
89     else if (corner == prop_atoms.net_wm_moveresize_move_keyboard)
90         cur = ob_cursors.move;
91     else
92         g_assert_not_reached();
93
94     grab_keyboard(TRUE);
95     grab_pointer(TRUE, cur);
96 }
97
98 void moveresize_event(XEvent *e)
99 {
100     g_assert(moveresize_in_progress);
101
102     if (e->type == MotionNotify) {
103         if (moving) {
104             cur_x = start_cx + e->xmotion.x_root - start_x;
105             cur_y = start_cy + e->xmotion.y_root - start_y;
106
107             dispatch_move(client, &cur_x, &cur_y);
108
109             popup_coords("X:  %d  Y:  %d", cur_x, cur_y);
110
111             /* get where the client should be */
112             frame_frame_gravity(client->frame, &cur_x, &cur_y);
113             client_configure(client, Corner_TopLeft, cur_x, cur_y,
114                              start_cw, start_ch, TRUE, FALSE);
115         } else {
116             if (corner == prop_atoms.net_wm_moveresize_size_topleft) {
117                 cur_x = start_cw - (e->xmotion.x_root - start_x);
118                 cur_y = start_ch - (e->xmotion.y_root - start_y);
119                 lockcorner = Corner_BottomRight;
120             } else if (corner == prop_atoms.net_wm_moveresize_size_top) {
121                 cur_x = start_cw;
122                 cur_y = start_ch - (e->xmotion.y_root - start_y);
123                 lockcorner = Corner_BottomRight;
124             } else if (corner == prop_atoms.net_wm_moveresize_size_topright) {
125                 cur_x = start_cw + (e->xmotion.x_root - start_x);
126                 cur_y = start_ch - (e->xmotion.y_root - start_y);
127                 lockcorner = Corner_BottomLeft;
128             } else if (corner == prop_atoms.net_wm_moveresize_size_right) { 
129                 cur_x = start_cw + (e->xmotion.x_root - start_x);
130                 cur_y = start_ch;
131                 lockcorner = Corner_BottomLeft;
132             } else if (corner ==
133                        prop_atoms.net_wm_moveresize_size_bottomright) {
134                 cur_x = start_cw + (e->xmotion.x_root - start_x);
135                 cur_y = start_ch + (e->xmotion.y_root - start_y);
136                 lockcorner = Corner_TopLeft;
137             } else if (corner == prop_atoms.net_wm_moveresize_size_bottom) {
138                 cur_x = start_cw;
139                 cur_y = start_ch + (e->xmotion.y_root - start_y);
140                 lockcorner = Corner_TopLeft;
141             } else if (corner ==
142                        prop_atoms.net_wm_moveresize_size_bottomleft) {
143                 cur_x = start_cw - (e->xmotion.x_root - start_x);
144                 cur_y = start_ch + (e->xmotion.y_root - start_y);
145                 lockcorner = Corner_TopRight;
146             } else if (corner == prop_atoms.net_wm_moveresize_size_left) {
147                 cur_x = start_cw - (e->xmotion.x_root - start_x);
148                 cur_y = start_ch;
149                 lockcorner = Corner_TopRight;
150             } else if (corner == prop_atoms.net_wm_moveresize_size_keyboard) {
151                 cur_x = start_cw + (e->xmotion.x_root - start_x);
152                 cur_y = start_ch + (e->xmotion.y_root - start_y);
153                 lockcorner = Corner_TopLeft;
154             } else
155                 g_assert_not_reached();
156
157             /* dispatch_resize needs the frame size */
158             cur_x += client->frame->size.left + client->frame->size.right;
159             cur_y += client->frame->size.top + client->frame->size.bottom;
160
161             dispatch_resize(client, &cur_x, &cur_y, lockcorner);
162
163             cur_x -= client->frame->size.left + client->frame->size.right;
164             cur_y -= client->frame->size.top + client->frame->size.bottom;
165     
166             client_configure(client, lockcorner, client->area.x,
167                              client->area.y, cur_x, cur_y, TRUE, FALSE);
168
169             popup_coords("W:  %d  H:  %d", client->logical_size.width,
170                          client->logical_size.height);
171         }
172     } else if (e->type == ButtonRelease) {
173         if (e->xbutton.button == button) {
174             grab_keyboard(FALSE);
175             grab_pointer(FALSE, None);
176
177             XDestroyWindow(ob_display, coords);
178             coords = None;
179
180             moveresize_in_progress = FALSE;
181
182             if (moving) {
183                 client_configure(client, Corner_TopLeft, cur_x, cur_y,
184                                  start_cw, start_ch, TRUE, TRUE);
185             } else {
186                 client_configure(client, lockcorner, client->area.x,
187                                  client->area.y, cur_x, cur_y, TRUE, TRUE);
188             }
189         }
190     } else if (e->type == KeyPress) {
191     }
192 }