added key command StartTabbing
This commit is contained in:
parent
c7b698757f
commit
0a14d911c6
9 changed files with 114 additions and 78 deletions
|
@ -1,5 +1,8 @@
|
||||||
(Format: Year/Month/Day)
|
(Format: Year/Month/Day)
|
||||||
Changes for 1.0.1:
|
Changes for 1.0.1:
|
||||||
|
*07/12/21:
|
||||||
|
* Added new key command :StartTabbing (Mark)
|
||||||
|
Window.cc/hh CurrentWindowCmd.cc/hh
|
||||||
*07/12/20:
|
*07/12/20:
|
||||||
* Added new key command :ForEach (or :Map) (Mark)
|
* Added new key command :ForEach (or :Map) (Mark)
|
||||||
- :ForEach {<command>} [{ [{<list opts>}] [<bool command>] }]
|
- :ForEach {<command>} [{ [{<list opts>}] [<bool command>] }]
|
||||||
|
|
|
@ -30,4 +30,4 @@ session.colorsPerChannel: 4
|
||||||
session.doubleClickInterval: 250
|
session.doubleClickInterval: 250
|
||||||
session.cacheMax: 200
|
session.cacheMax: 200
|
||||||
session.imageDither: True
|
session.imageDither: True
|
||||||
session.configVersion: 6
|
session.configVersion: 7
|
||||||
|
|
|
@ -15,6 +15,9 @@ OnToolbar Mouse5 :PrevWorkspace
|
||||||
OnWindow Mod1 Mouse1 :StartMoving
|
OnWindow Mod1 Mouse1 :StartMoving
|
||||||
OnWindow Mod1 Mouse3 :StartResizing
|
OnWindow Mod1 Mouse3 :StartResizing
|
||||||
|
|
||||||
|
# middle click a window's titlebar and drag to attach windows
|
||||||
|
OnTitlebar Mouse2 :StartTabbing
|
||||||
|
|
||||||
# double click on the titlebar to shade
|
# double click on the titlebar to shade
|
||||||
OnTitlebar Double Mouse1 :Shade
|
OnTitlebar Double Mouse1 :Shade
|
||||||
|
|
||||||
|
|
|
@ -313,6 +313,16 @@ void StartResizingCmd::real_execute() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REGISTER_OBJECT(starttabbing, StartTabbingCmd, Command);
|
||||||
|
|
||||||
|
void StartTabbingCmd::real_execute() {
|
||||||
|
const XEvent &last = Fluxbox::instance()->lastEvent();
|
||||||
|
if (last.type == ButtonPress) {
|
||||||
|
const XButtonEvent &be = last.xbutton;
|
||||||
|
fbwindow().startTabbing(be);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FbTk::Command *MoveCmd::parse(const string &command, const string &args,
|
FbTk::Command *MoveCmd::parse(const string &command, const string &args,
|
||||||
bool trusted) {
|
bool trusted) {
|
||||||
FbTk_istringstream is(args.c_str());
|
FbTk_istringstream is(args.c_str());
|
||||||
|
|
|
@ -159,6 +159,14 @@ private:
|
||||||
const FluxboxWindow::ResizeModel m_mode;
|
const FluxboxWindow::ResizeModel m_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// begin tabbing with mouse
|
||||||
|
class StartTabbingCmd: public WindowHelperCmd {
|
||||||
|
public:
|
||||||
|
StartTabbingCmd() { }
|
||||||
|
protected:
|
||||||
|
void real_execute();
|
||||||
|
};
|
||||||
|
|
||||||
// move cmd, relative position
|
// move cmd, relative position
|
||||||
class MoveCmd: public WindowHelperCmd {
|
class MoveCmd: public WindowHelperCmd {
|
||||||
public:
|
public:
|
||||||
|
|
149
src/Window.cc
149
src/Window.cc
|
@ -2611,11 +2611,10 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
|
||||||
me.window = frame().window().window();
|
me.window = frame().window().window();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inside_titlebar = (frame().titlebar() == me.window
|
bool inside_titlebar = frame().gripLeft().window() != me.window &&
|
||||||
|| frame().label() == me.window
|
frame().gripRight().window() != me.window &&
|
||||||
|| frame().tabcontainer() == me.window
|
frame().clientArea().window() != me.window &&
|
||||||
|| frame().handle() == me.window
|
frame().window() != me.window;
|
||||||
|| frame().window() == me.window);
|
|
||||||
|
|
||||||
if (Fluxbox::instance()->getIgnoreBorder() && m_attaching_tab == 0
|
if (Fluxbox::instance()->getIgnoreBorder() && m_attaching_tab == 0
|
||||||
&& !(isMoving() || isResizing())) {
|
&& !(isMoving() || isResizing())) {
|
||||||
|
@ -2650,24 +2649,8 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WinClient *client = 0;
|
if (moving || (me.state & Button1Mask) && functions.move &&
|
||||||
if (!inside_titlebar) {
|
inside_titlebar && !isResizing() && m_attaching_tab == 0) {
|
||||||
// determine if we're in titlebar
|
|
||||||
Client2ButtonMap::iterator it =
|
|
||||||
find_if(m_labelbuttons.begin(),
|
|
||||||
m_labelbuttons.end(),
|
|
||||||
Compose(bind2nd(equal_to<Window>(), me.window),
|
|
||||||
Compose(mem_fun(&TextButton::window),
|
|
||||||
Select2nd<Client2ButtonMap::value_type>())));
|
|
||||||
if (it != m_labelbuttons.end()) {
|
|
||||||
inside_titlebar = true;
|
|
||||||
client = (*it).first;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((me.state & Button1Mask) && functions.move &&
|
|
||||||
inside_titlebar &&
|
|
||||||
!isResizing()) {
|
|
||||||
|
|
||||||
if (! isMoving()) {
|
if (! isMoving()) {
|
||||||
startMoving(me.x_root, me.y_root);
|
startMoving(me.x_root, me.y_root);
|
||||||
|
@ -2741,7 +2724,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
|
||||||
|
|
||||||
screen().showPosition(dx, dy);
|
screen().showPosition(dx, dy);
|
||||||
} // end if moving
|
} // end if moving
|
||||||
} else if (functions.resize &&
|
} else if (resizing || m_attaching_tab == 0 && functions.resize &&
|
||||||
(((me.state & Button1Mask) &&
|
(((me.state & Button1Mask) &&
|
||||||
(me.window == frame().gripRight() ||
|
(me.window == frame().gripRight() ||
|
||||||
me.window == frame().gripLeft())) ||
|
me.window == frame().gripLeft())) ||
|
||||||
|
@ -2833,61 +2816,25 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
|
||||||
screen().showGeometry(gx, gy);
|
screen().showGeometry(gx, gy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (functions.tabable &&
|
} else if (m_attaching_tab != 0) {
|
||||||
(me.state & Button2Mask) && inside_titlebar && (client != 0 || m_attaching_tab != 0)) {
|
|
||||||
//
|
//
|
||||||
// drag'n'drop code for tabs
|
// drag'n'drop code for tabs
|
||||||
//
|
//
|
||||||
FbTk::TextButton &active_button = *m_labelbuttons[(m_attaching_tab==0)?client:m_attaching_tab];
|
|
||||||
|
|
||||||
if (m_attaching_tab == 0) {
|
// we already grabed and started to drag'n'drop tab
|
||||||
if (s_num_grabs > 0)
|
// so we update drag'n'drop-rectangle
|
||||||
return;
|
int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y;
|
||||||
// start drag'n'drop for tab
|
|
||||||
m_attaching_tab = client;
|
|
||||||
grabPointer(me.window, False, ButtonMotionMask |
|
|
||||||
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
|
|
||||||
None, frame(). theme().moveCursor(), CurrentTime);
|
|
||||||
// relative position on button
|
|
||||||
m_button_grab_x = me.x;
|
|
||||||
m_button_grab_y = me.y;
|
|
||||||
// last known root mouse position
|
|
||||||
m_last_move_x = me.x_root - me.x;
|
|
||||||
m_last_move_y = me.y_root - me.y;
|
|
||||||
// hijack extra vars for initial grab location
|
|
||||||
m_last_resize_x = me.x_root;
|
|
||||||
m_last_resize_y = me.y_root;
|
|
||||||
|
|
||||||
Fluxbox::instance()->grab();
|
parent().drawRectangle(screen().rootTheme().opGC(),
|
||||||
|
m_last_move_x, m_last_move_y,
|
||||||
|
m_last_resize_w, m_last_resize_h);
|
||||||
|
parent().drawRectangle(screen().rootTheme().opGC(),
|
||||||
|
dx, dy,
|
||||||
|
m_last_resize_w, m_last_resize_h);
|
||||||
|
|
||||||
parent().drawRectangle(screen().rootTheme().opGC(),
|
// change remembered position of rectangle
|
||||||
m_last_move_x, m_last_move_y,
|
m_last_move_x = dx;
|
||||||
active_button.width(),
|
m_last_move_y = dy;
|
||||||
active_button.height());
|
|
||||||
|
|
||||||
menu().hide();
|
|
||||||
} else {
|
|
||||||
// we already grabed and started to drag'n'drop tab
|
|
||||||
// so we update drag'n'drop-rectangle
|
|
||||||
int dx = me.x_root - m_button_grab_x, dy = me.y_root - m_button_grab_y;
|
|
||||||
|
|
||||||
//erase rectangle
|
|
||||||
parent().drawRectangle(screen().rootTheme().opGC(),
|
|
||||||
m_last_move_x, m_last_move_y,
|
|
||||||
active_button.width(),
|
|
||||||
active_button.height());
|
|
||||||
|
|
||||||
|
|
||||||
// redraw rectangle at new pos
|
|
||||||
m_last_move_x = dx;
|
|
||||||
m_last_move_y = dy;
|
|
||||||
parent().drawRectangle(screen().rootTheme().opGC(),
|
|
||||||
m_last_move_x, m_last_move_y,
|
|
||||||
active_button.width(),
|
|
||||||
active_button.height());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3116,7 +3063,7 @@ void FluxboxWindow::startMoving(int x, int y) {
|
||||||
Fluxbox *fluxbox = Fluxbox::instance();
|
Fluxbox *fluxbox = Fluxbox::instance();
|
||||||
// grabbing (and masking) on the root window allows us to
|
// grabbing (and masking) on the root window allows us to
|
||||||
// freely map and unmap the window we're moving.
|
// freely map and unmap the window we're moving.
|
||||||
grabPointer(screen().rootWindow().window(), False, Button1MotionMask |
|
grabPointer(screen().rootWindow().window(), False, ButtonMotionMask |
|
||||||
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
|
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
|
||||||
screen().rootWindow().window(), frame().theme().moveCursor(), CurrentTime);
|
screen().rootWindow().window(), frame().theme().moveCursor(), CurrentTime);
|
||||||
|
|
||||||
|
@ -3467,14 +3414,64 @@ void FluxboxWindow::stopResizing(bool interrupted) {
|
||||||
ungrabPointer(CurrentTime);
|
ungrabPointer(CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FluxboxWindow::startTabbing(const XButtonEvent &be) {
|
||||||
|
|
||||||
|
if (s_num_grabs > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_attaching_tab = 0;
|
||||||
|
// determine if we're in titlebar
|
||||||
|
Client2ButtonMap::iterator it =
|
||||||
|
find_if(m_labelbuttons.begin(),
|
||||||
|
m_labelbuttons.end(),
|
||||||
|
Compose(bind2nd(equal_to<Window>(), be.window),
|
||||||
|
Compose(mem_fun(&TextButton::window),
|
||||||
|
Select2nd<Client2ButtonMap::value_type>())));
|
||||||
|
if (it != m_labelbuttons.end())
|
||||||
|
m_attaching_tab = it->first;
|
||||||
|
|
||||||
|
// start drag'n'drop for tab
|
||||||
|
grabPointer(be.window, False, ButtonMotionMask |
|
||||||
|
ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
|
||||||
|
None, frame().theme().moveCursor(), CurrentTime);
|
||||||
|
|
||||||
|
// relative position on the button
|
||||||
|
m_button_grab_x = be.x;
|
||||||
|
m_button_grab_y = be.y;
|
||||||
|
// position of the button
|
||||||
|
m_last_move_x = be.x_root - be.x;
|
||||||
|
m_last_move_y = be.y_root - be.y;
|
||||||
|
// hijack extra vars for initial grab location
|
||||||
|
m_last_resize_x = be.x_root;
|
||||||
|
m_last_resize_y = be.y_root;
|
||||||
|
|
||||||
|
Fluxbox::instance()->grab();
|
||||||
|
|
||||||
|
if (m_attaching_tab) {
|
||||||
|
FbTk::TextButton &active_button = *m_labelbuttons[m_attaching_tab];
|
||||||
|
m_last_resize_w = active_button.width();
|
||||||
|
m_last_resize_h = active_button.height();
|
||||||
|
} else {
|
||||||
|
m_attaching_tab = m_client;
|
||||||
|
unsigned int bw = 2*frame().window().borderWidth()-1;
|
||||||
|
m_last_resize_w = frame().width() + bw;
|
||||||
|
m_last_resize_h = frame().height() + bw;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent().drawRectangle(screen().rootTheme().opGC(),
|
||||||
|
m_last_move_x, m_last_move_y,
|
||||||
|
m_last_resize_w, m_last_resize_h);
|
||||||
|
|
||||||
|
menu().hide();
|
||||||
|
}
|
||||||
|
|
||||||
void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
|
void FluxboxWindow::attachTo(int x, int y, bool interrupted) {
|
||||||
if (m_attaching_tab == 0)
|
if (m_attaching_tab == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parent().drawRectangle(screen().rootTheme().opGC(),
|
parent().drawRectangle(screen().rootTheme().opGC(),
|
||||||
m_last_move_x, m_last_move_y,
|
m_last_move_x, m_last_move_y,
|
||||||
m_labelbuttons[m_attaching_tab]->width(),
|
m_last_resize_w, m_last_resize_h);
|
||||||
m_labelbuttons[m_attaching_tab]->height());
|
|
||||||
|
|
||||||
ungrabPointer(CurrentTime);
|
ungrabPointer(CurrentTime);
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,8 @@ public:
|
||||||
ResizeDirection getResizeDirection(int x, int y, ResizeModel model);
|
ResizeDirection getResizeDirection(int x, int y, ResizeModel model);
|
||||||
/// stops the resizing
|
/// stops the resizing
|
||||||
void stopResizing(bool interrupted = false);
|
void stopResizing(bool interrupted = false);
|
||||||
|
/// starts tabbing
|
||||||
|
void startTabbing(const XButtonEvent &be);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name accessors
|
@name accessors
|
||||||
|
|
|
@ -643,7 +643,7 @@ void Fluxbox::setupConfigFiles() {
|
||||||
if (create_init)
|
if (create_init)
|
||||||
FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
|
FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
|
||||||
|
|
||||||
#define CONFIG_VERSION 6
|
#define CONFIG_VERSION 7
|
||||||
FbTk::Resource<int> config_version(m_resourcemanager, 0,
|
FbTk::Resource<int> config_version(m_resourcemanager, 0,
|
||||||
"session.configVersion", "Session.ConfigVersion");
|
"session.configVersion", "Session.ConfigVersion");
|
||||||
if (*config_version < CONFIG_VERSION) {
|
if (*config_version < CONFIG_VERSION) {
|
||||||
|
|
|
@ -275,6 +275,19 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
|
||||||
new_version = 6;
|
new_version = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_version < 7) { // added StartTabbing command
|
||||||
|
string whole_keyfile = read_file(keyfilename);
|
||||||
|
string new_keyfile = "";
|
||||||
|
// let's put our new keybindings first, so they're easy to find
|
||||||
|
new_keyfile += "# start tabbing windows together\n";
|
||||||
|
new_keyfile += "OnTitlebar Mouse2 :StartTabbing\n\n";
|
||||||
|
new_keyfile += whole_keyfile; // don't forget user's old keybindings
|
||||||
|
|
||||||
|
write_file(keyfilename, new_keyfile);
|
||||||
|
|
||||||
|
new_version = 7;
|
||||||
|
}
|
||||||
|
|
||||||
return new_version;
|
return new_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue