[Thread Prev][Thread Next]   >Date Index >Thread Index

[wmx] A new way to switch channels

Lasse Rasinen - Fri Apr 14 21:59:17 2000

OK, first some background: My brother (also a satisfied wmx user) said
"The only thing that really sucks is moving windows to other channels."
and then described a neat way to do it with a menu. So I said: 
"No problem, I can do it in 30 minutes." (It took an hour, though,
since I've lately done OO stuff with Java, so I kinda forgot the abysmal
C++ syntax ;)

This patch was written on wmx-5, since it was handy and available.
Hopefully it applies cleanly to newer releases too, I haven't tried.

UI changes: Button2 on tab or border brings up a window listing all the
channels, pick one and then window moves there (and changes the current
channel too). Button2 on the channel switch area brings up the same menu,
choose and the current channel changes. Works nicely.

Code changes: I added public WindowManager::gotoChannel(int, Client *) and
public WindowManager::channels(). The Alt-Fns use gotoChannel() too.

Does not leak memory AFAIK ;)

Any comments on usability and/or philosophical issues? 
("Egads, it's almost like mainstream window managers! Heretic!")

diff -u old-wmx5/Buttons.C hacking/Buttons.C
--- old-wmx5/Buttons.C	Wed Jan 13 12:28:43 1999
+++ hacking/Buttons.C	Fri Apr 14 20:54:09 2000
@@ -25,13 +25,7 @@
 		   e->y < CONFIG_CHANNEL_CLICK_SIZE) {
 
 	    if (e->button == Button2) {
-
-		if (m_channelChangeTime == 0) flipChannel(True, False, False,0);
-		else flipChannel(False, False, False, 0);
-
-	    } else if (e->button == Button1 && m_channelChangeTime != 0) {
-
-		flipChannel(False, True, False, 0);
+		ChannelMenu(this, (XEvent *)e);
 	    }
 
 	} else if (e->button == Button2 && m_channelChangeTime == 0) {
@@ -42,8 +36,7 @@
     } else if (c) {
 
 	if (e->button == Button2 && CONFIG_CHANNEL_SURF) {
-	    if (m_channelChangeTime == 0) flipChannel(True, False, False, 0);
-	    else flipChannel(False, False, False, c);
+	    ChannelMenu menu(this, (XEvent *)e);
 	    return;
 	}
 
@@ -121,23 +114,9 @@
 		CONFIG_CHANNEL_SURF && CONFIG_USE_CHANNEL_KEYS) {
 
 		int channel = key - XK_F1 + 1;
-	    
-		if (channel == m_currentChannel) {
-
-		    flipChannel(True, False, False, 0);
-
-		} else if (channel > 0 && channel <= m_channels) {
-
-		    while (m_currentChannel != channel) {
-			if (m_currentChannel < channel) {
-			    flipChannel(False, False, True, 0);
-			} else {
-			    flipChannel(False, True, True, 0);
-			}
-			XSync(display(), False);
-		    }
-		}
 
+		gotoChannel(channel, 0);
+		
 	    } else {
 
 		// These key names also appear in Client::manage(), so
diff -u old-wmx5/Channel.C hacking/Channel.C
--- old-wmx5/Channel.C	Wed Jan 13 12:28:43 1999
+++ hacking/Channel.C	Fri Apr 14 20:05:38 2000
@@ -164,4 +164,22 @@
     ++m_channels;
 }
 
+void WindowManager::gotoChannel(int channel, Client *push)
+{
+    if (channel == m_currentChannel) {
+	flipChannel(True, False, False, 0);
+	return;
+   }
 
+    if (channel > 0 && channel <= m_channels) {
+
+	while (m_currentChannel != channel) {
+	    if (m_channels < channel) {
+		flipChannel(False, False, True, push);
+	    } else {
+		flipChannel(False, True, True, push);
+	    }
+	    XSync(display(), False);
+	}
+    }
+}
diff -u old-wmx5/Manager.h hacking/Manager.h
--- old-wmx5/Manager.h	Wed Jan 13 12:28:43 1999
+++ hacking/Manager.h	Fri Apr 14 20:12:05 2000
@@ -63,8 +63,10 @@
     void spawn(char *, char *);
 
     int channel() { return m_currentChannel; }
+    int channels() { return m_channels; }
     void setSignalled() { m_looping = False; } // ...
-
+    void gotoChannel(int channel, Client *push);
+    
     ClientList &clients() { return m_clients; }
     ClientList &hiddenClients() { return m_hiddenClients; }
 
diff -u old-wmx5/Menu.C hacking/Menu.C
--- old-wmx5/Menu.C	Wed Jan 13 12:28:43 1999
+++ hacking/Menu.C	Fri Apr 14 22:41:36 2000
@@ -686,7 +686,43 @@
     return items;
 }
 
+ChannelMenu::ChannelMenu(WindowManager *manager, XEvent *e)
+    : Menu(manager, e), m_channels(manager->channels()),
+      m_channel(manager->channel())
+{
+    XButtonEvent *ev = (XButtonEvent *)e;
 
+    Client *c = m_windowManager->windowToClient(ev->window);
+    ev->x = ev->x_root; ev->y = ev->y_root;
+	
+    int channel = getSelection() + 1;
+
+    m_windowManager->gotoChannel(channel, c);
+}
+
+ChannelMenu::~ChannelMenu()
+{
+    for (int i = 0; i < m_channels; i++) {
+	free(m_items[i]);
+    }
+    free(m_items);
+}
+
+char **ChannelMenu::getItems(int *niR, int *nhR)
+{
+    *niR = m_windowManager->channels();
+    *nhR = 0;
+
+    char **items = (char **)malloc(*niR * sizeof(char *));
+    for (int i = 0; i < *niR; i++) {
+	char temp[50]; // Warning! Works only, if int < 136 bits.
+	sprintf(temp, "Channel %d", i + 1);
+	char *item = (char *)malloc(strlen(temp) + 1);
+	strcpy (item, temp);
+	items[i] = item;
+    }
+    return m_items = items;
+}
 // Fake geometry as a "menu" to save on code
 
 ShowGeometry::ShowGeometry(WindowManager *manager, XEvent *e)
diff -u old-wmx5/Menu.h hacking/Menu.h
--- old-wmx5/Menu.h	Wed Jan 13 12:28:43 1999
+++ hacking/Menu.h	Fri Apr 14 20:10:11 2000
@@ -62,6 +62,19 @@
     virtual void raiseFeedbackLevel(int);
 };
 
+class ChannelMenu : public Menu
+{
+ public:
+    ChannelMenu(WindowManager *, XEvent *e);
+    virtual ~ChannelMenu();
+
+ private:
+    virtual char **getItems(int *, int *);
+    int m_channel;
+    int m_channels;
+    char **m_items;
+};
+
 class CommandMenu : public Menu
 {
 public:
-- 
Lasse Rasinen                       I put it all down in a letter once      
lrasinen@iki.fi                     A letter I don't send                   
                                    It made me feel much better at the time 
                                    I thought it'd help me mend


Next: