Skip to content

Commit 06c2bda

Browse files
authored
Merge pull request #35 from aesophor/staging
Add support for moving / resizing floating windows with keybinds #18
2 parents 3cb31bd + f51a061 commit 06c2bda

File tree

12 files changed

+198
-24
lines changed

12 files changed

+198
-24
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.9)
2-
project(wmderland VERSION 1.0.3)
2+
project(wmderland VERSION 1.0.4)
33

44
# There are two CMake scripts in ./cmake
55
# 1. BuildType.cmake - determine build type on demand

example/config

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ set min_window_height = 100
2323
set focused_color = ff596e84
2424
set unfocused_color = ff394859
2525
set focus_follows_mouse = true
26-
set $Mod = Mod4
26+
27+
set $Alt = Mod1
28+
set $Cmd = Mod4
29+
set $Mod = $Cmd
2730

2831

2932
; [Spawning Rules]
@@ -121,8 +124,16 @@ bindsym $Mod+Shift+9 move_window_to_workspace 9
121124

122125
bindsym $Mod+h navigate_left
123126
bindsym $Mod+l navigate_right
124-
bindsym $Mod+j navigate_down
125127
bindsym $Mod+k navigate_up
128+
bindsym $Mod+j navigate_down
129+
bindsym $Mod+$Alt+Shift+h float_move_left
130+
bindsym $Mod+$Alt+Shift+l float_move_right
131+
bindsym $Mod+$Alt+Shift+k float_move_up
132+
bindsym $Mod+$Alt+Shift+j float_move_down
133+
bindsym $Mod+$Alt+h float_resize_left
134+
bindsym $Mod+$Alt+l float_resize_right
135+
bindsym $Mod+$Alt+k float_resize_up
136+
bindsym $Mod+$Alt+j float_resize_down
126137
bindsym $Mod+g tile_h
127138
bindsym $Mod+v tile_v
128139
bindsym $Mod+Shift+space toggle_floating

ipc-client/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.9)
2-
project(wmderlandc VERSION 1.0.3)
2+
project(wmderlandc VERSION 1.0.4)
33

44
# Find the required libraries.
55
find_package(X11 REQUIRED)

src/action.cc

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,26 @@ Action::Type Action::StrToActionType(const string& s) {
4141
return Action::Type::NAVIGATE_LEFT;
4242
} else if (s == "navigate_right") {
4343
return Action::Type::NAVIGATE_RIGHT;
44-
} else if (s == "navigate_down") {
45-
return Action::Type::NAVIGATE_DOWN;
4644
} else if (s == "navigate_up") {
4745
return Action::Type::NAVIGATE_UP;
46+
} else if (s == "navigate_down") {
47+
return Action::Type::NAVIGATE_DOWN;
48+
} else if (s == "float_move_left") {
49+
return Action::Type::FLOAT_MOVE_LEFT;
50+
} else if (s == "float_move_right") {
51+
return Action::Type::FLOAT_MOVE_RIGHT;
52+
} else if (s == "float_move_up") {
53+
return Action::Type::FLOAT_MOVE_UP;
54+
} else if (s == "float_move_down") {
55+
return Action::Type::FLOAT_MOVE_DOWN;
56+
} else if (s == "float_resize_left") {
57+
return Action::Type::FLOAT_RESIZE_LEFT;
58+
} else if (s == "float_resize_right") {
59+
return Action::Type::FLOAT_RESIZE_RIGHT;
60+
} else if (s == "float_resize_up") {
61+
return Action::Type::FLOAT_RESIZE_UP;
62+
} else if (s == "float_resize_down") {
63+
return Action::Type::FLOAT_RESIZE_DOWN;
4864
} else if (s == "tile_h") {
4965
return Action::Type::TILE_H;
5066
} else if (s == "tile_v") {

src/action.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,16 @@ class Action {
1111
enum class Type {
1212
NAVIGATE_LEFT,
1313
NAVIGATE_RIGHT,
14-
NAVIGATE_DOWN,
1514
NAVIGATE_UP,
15+
NAVIGATE_DOWN,
16+
FLOAT_MOVE_LEFT,
17+
FLOAT_MOVE_RIGHT,
18+
FLOAT_MOVE_UP,
19+
FLOAT_MOVE_DOWN,
20+
FLOAT_RESIZE_LEFT,
21+
FLOAT_RESIZE_RIGHT,
22+
FLOAT_RESIZE_UP,
23+
FLOAT_RESIZE_DOWN,
1624
TILE_H,
1725
TILE_V,
1826
TOGGLE_FLOATING,

src/client.cc

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2018-2019 Marco Wang <[email protected]>
1+
// Copyright (c) 2018-2020 Marco Wang <[email protected]>
22
#include "client.h"
33

44
#include "config.h"
@@ -50,16 +50,44 @@ void Client::Raise() const {
5050
XRaiseWindow(dpy_, window_);
5151
}
5252

53-
void Client::Move(int x, int y) const {
54-
XMoveWindow(dpy_, window_, x, y);
53+
void Client::Move(int x, int y, bool absolute) const {
54+
if (absolute) {
55+
XMoveWindow(dpy_, window_, x, y);
56+
return;
57+
}
58+
59+
XWindowAttributes attr = GetXWindowAttributes();
60+
XMoveWindow(dpy_, window_, attr.x + x, attr.y + y);
5561
}
5662

57-
void Client::Resize(int w, int h) const {
63+
void Client::Resize(int w, int h, bool absolute) const {
64+
if (absolute) {
65+
ConstrainSize(w, h);
66+
XResizeWindow(dpy_, window_, w, h);
67+
return;
68+
}
69+
70+
// Resize window by relative width and height.
71+
XWindowAttributes attr = GetXWindowAttributes();
72+
w = attr.width + w;
73+
h = attr.height + h;
74+
ConstrainSize(w, h);
5875
XResizeWindow(dpy_, window_, w, h);
5976
}
6077

61-
void Client::MoveResize(int x, int y, int w, int h) const {
62-
XMoveResizeWindow(dpy_, window_, x, y, w, h);
78+
void Client::MoveResize(int x, int y, int w, int h, bool absolute) const {
79+
if (absolute) {
80+
ConstrainSize(w, h);
81+
XMoveResizeWindow(dpy_, window_, x, y, w, h);
82+
return;
83+
}
84+
85+
// Resize window by relative width and height.
86+
XWindowAttributes attr = GetXWindowAttributes();
87+
w = attr.width + w;
88+
h = attr.height + h;
89+
ConstrainSize(w, h);
90+
XMoveResizeWindow(dpy_, window_, attr.x + x, attr.y + y, w, h);
6391
}
6492

6593
void Client::MoveResize(int x, int y, const std::pair<int, int>& size) const {
@@ -86,6 +114,56 @@ XWindowAttributes Client::GetXWindowAttributes() const {
86114
return wm_utils::GetXWindowAttributes(window_);
87115
}
88116

117+
void Client::Move(const Action& action) const {
118+
const int& move_step = workspace_->config()->float_move_step();
119+
int x_offset = 0;
120+
int y_offset = 0;
121+
122+
switch (action.type()) {
123+
case Action::Type::FLOAT_MOVE_LEFT:
124+
x_offset = -move_step;
125+
break;
126+
case Action::Type::FLOAT_MOVE_RIGHT:
127+
x_offset = move_step;
128+
break;
129+
case Action::Type::FLOAT_MOVE_UP:
130+
y_offset = -move_step;
131+
break;
132+
case Action::Type::FLOAT_MOVE_DOWN:
133+
y_offset = move_step;
134+
break;
135+
default:
136+
break;
137+
}
138+
139+
Move(x_offset, y_offset, /*absolute=*/false);
140+
}
141+
142+
void Client::Resize(const Action& action) const {
143+
const int& resize_step = workspace_->config()->float_resize_step();
144+
int width_offset = 0;
145+
int height_offset = 0;
146+
147+
switch (action.type()) {
148+
case Action::Type::FLOAT_RESIZE_LEFT:
149+
width_offset = -resize_step;
150+
break;
151+
case Action::Type::FLOAT_RESIZE_RIGHT:
152+
width_offset = resize_step;
153+
break;
154+
case Action::Type::FLOAT_RESIZE_UP:
155+
height_offset = -resize_step;
156+
break;
157+
case Action::Type::FLOAT_RESIZE_DOWN:
158+
height_offset = resize_step;
159+
break;
160+
default:
161+
break;
162+
}
163+
164+
Resize(width_offset, height_offset, /*absolute=*/false);
165+
}
166+
89167
Window Client::window() const {
90168
return window_;
91169
}
@@ -142,6 +220,13 @@ void Client::set_attr_cache(const XWindowAttributes& attr) {
142220
attr_cache_ = attr;
143221
}
144222

223+
void Client::ConstrainSize(int& w, int& h) const {
224+
const int min_w = (size_hints_.flags & PMinSize) ? size_hints_.min_width : MIN_WINDOW_WIDTH;
225+
const int min_h = (size_hints_.flags & PMinSize) ? size_hints_.min_height : MIN_WINDOW_HEIGHT;
226+
w = (w < min_w) ? min_w : w;
227+
h = (h < min_h) ? min_h : h;
228+
}
229+
145230
Client::Area::Area() : x(), y(), w(), h() {}
146231

147232
Client::Area::Area(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) {}

src/client.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extern "C" {
88
}
99
#include <string>
1010
#include <unordered_map>
11+
#include "action.h"
1112

1213
namespace wmderland {
1314

@@ -35,16 +36,19 @@ class Client {
3536
void Map() const;
3637
void Unmap();
3738
void Raise() const;
38-
void Move(int x, int y) const;
39-
void Resize(int w, int h) const;
40-
void MoveResize(int x, int y, int w, int h) const;
39+
void Move(int x, int y, bool absolute = true) const;
40+
void Resize(int w, int h, bool absolute = true) const;
41+
void MoveResize(int x, int y, int w, int h, bool absolute = true) const;
4142
void MoveResize(int x, int y, const std::pair<int, int>& size) const;
4243
void SetInputFocus() const;
4344
void SetBorderWidth(unsigned int width) const;
4445
void SetBorderColor(unsigned long color) const;
4546
void SelectInput(long input_mask) const;
4647
XWindowAttributes GetXWindowAttributes() const;
4748

49+
void Move(const Action& action) const; // FLOAT_MOVE_{LEFT,RIGHT,UP,DOWN}
50+
void Resize(const Action& action) const; // FLOAT_RESIZE_{LEFT,RIGHT,UP,DOWN}
51+
4852
Window window() const;
4953
Workspace* workspace() const;
5054
const XSizeHints& size_hints() const;
@@ -63,6 +67,8 @@ class Client {
6367
void set_attr_cache(const XWindowAttributes& attr);
6468

6569
private:
70+
void ConstrainSize(int& w, int& h) const;
71+
6672
Display* dpy_;
6773
Window window_;
6874
Workspace* workspace_;

src/config.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ unsigned int Config::min_window_height() const {
9393
return min_window_height_;
9494
}
9595

96+
unsigned int Config::float_move_step() const {
97+
return float_move_step_;
98+
}
99+
100+
unsigned int Config::float_resize_step() const {
101+
return float_resize_step_;
102+
}
103+
96104
unsigned long Config::focused_color() const {
97105
return focused_color_;
98106
}
@@ -171,6 +179,8 @@ ifstream& operator>>(ifstream& ifs, Config& config) {
171179
config.border_width_ = DEFAULT_BORDER_WIDTH;
172180
config.min_window_width_ = MIN_WINDOW_WIDTH;
173181
config.min_window_height_ = MIN_WINDOW_HEIGHT;
182+
config.float_move_step_ = DEFAULT_FLOAT_MOVE_STEP;
183+
config.float_resize_step_ = DEFAULT_FLOAT_RESIZE_STEP;
174184
config.focused_color_ = DEFAULT_FOCUSED_COLOR;
175185
config.unfocused_color_ = DEFAULT_UNFOCUSED_COLOR;
176186
config.focus_follows_mouse_ = DEFAULT_FOCUS_FOLLOWS_MOUSE;
@@ -223,6 +233,10 @@ ifstream& operator>>(ifstream& ifs, Config& config) {
223233
config.min_window_width_ = std::stoi(value);
224234
} else if (key == "min_window_height") {
225235
config.min_window_height_ = std::stoi(value);
236+
} else if (key == "float_move_step") {
237+
config.float_move_step_ = std::stoi(value);
238+
} else if (key == "float_resize_step") {
239+
config.float_resize_step_ = std::stoi(value);
226240
} else if (key == "focused_color") {
227241
config.focused_color_ = std::stoul(value, nullptr, 16);
228242
} else if (key == "unfocused_color") {

src/config.h.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ extern "C" {
3232

3333
#define DEFAULT_GAP_WIDTH 15
3434
#define DEFAULT_BORDER_WIDTH 3
35+
#define DEFAULT_FLOAT_MOVE_STEP 10
36+
#define DEFAULT_FLOAT_RESIZE_STEP 10
3537
#define DEFAULT_FOCUSED_COLOR 0xffffffff
3638
#define DEFAULT_UNFOCUSED_COLOR 0xff41485f
3739
#define DEFAULT_FOCUS_FOLLOWS_MOUSE true
@@ -57,6 +59,8 @@ class Config {
5759
unsigned int border_width() const;
5860
unsigned int min_window_width() const;
5961
unsigned int min_window_height() const;
62+
unsigned int float_move_step() const;
63+
unsigned int float_resize_step() const;
6064
unsigned long focused_color() const;
6165
unsigned long unfocused_color() const;
6266
bool focus_follows_mouse() const;
@@ -90,6 +94,8 @@ class Config {
9094
unsigned int border_width_;
9195
unsigned int min_window_width_;
9296
unsigned int min_window_height_;
97+
unsigned int float_move_step_;
98+
unsigned int float_resize_step_;
9399
unsigned long focused_color_;
94100
unsigned long unfocused_color_;
95101
bool focus_follows_mouse_;

src/main.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const char* version() {
1818
return WIN_MGR_NAME
1919
" " VERSION
2020
"\n"
21-
"Copyright (C) 2018-2019 Marco Wang <[email protected]>\n"
21+
"Copyright (C) 2018-2020 Marco Wang <[email protected]>\n"
2222
"This is free software, see the source for copying conditions. There is no\n"
2323
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE";
2424
}

0 commit comments

Comments
 (0)