After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 633994 - Window menu option to move to different monitor
Window menu option to move to different monitor
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on: 633645
Blocks: randr-tracker
 
 
Reported: 2010-11-04 14:47 UTC by Owen Taylor
Modified: 2015-04-14 21:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Hi anyone I write a simple patch to implement this feature, I think it can work in theory, but all gnome-shell freezed when I click "move to monitor 1" in the menu... So what is wrong? Thank you! (1.72 KB, patch)
2015-03-19 13:17 UTC, Isaac Ge
needs-work Details | Review
screen: Add public method to get neighboring monitor (3.20 KB, patch)
2015-03-22 13:48 UTC, Florian Müllner
committed Details | Review
windowMenu: Add option to move different monitor (2.88 KB, patch)
2015-03-23 03:22 UTC, Isaac Ge
none Details | Review
windowMenu: Add option to move different monitor (2.41 KB, patch)
2015-03-24 03:21 UTC, Isaac Ge
none Details | Review
windowMenu: Add option to move different monitor (2.41 KB, patch)
2015-03-24 09:26 UTC, Isaac Ge
committed Details | Review

Description Owen Taylor 2010-11-04 14:47:54 UTC
Suggestion from Matthias Clasen:

 https://bugzilla.redhat.com/show_bug.cgi?id=510084

===
The window menu has all those workspace related options, but with multiple
monitors, it is much more interesting to quickly move a window 'over' to the
other monitor. 

Might be a nice addition, and should of course only be shown if there are
multiple monitors...
===

Related to Metacity bug 439400 but duplicating here because we're really rethinking the multimonitor experience from scratch with GNOME Shell and planning to have our own window menu implementation.
Comment 1 Isaac Ge 2015-03-18 13:35:17 UTC
Could I ask that what is window menu? GMenu library?

I use i3 at before, it treat a momitor as a individual workspace, I think this is a good idea.
Comment 2 Florian Müllner 2015-03-18 17:04:51 UTC
(In reply to Isaac Ge from comment #1)
> Could I ask that what is window menu? GMenu library?

No, the window menu is the menu which pops up when you right-click the titlebar. It's implemented in js/ui/windowMenu.js nowadays.


> I use i3 at before, it treat a momitor as a individual workspace, I think
> this is a good idea.

That's completely unrelated to the bug and would be incompatible with the EWMH spec[0] (and thus break clients that rely on it, like 3rd party pagers/docks) ... not to mention massive rewrites of major parts of mutter.

[0] http://standards.freedesktop.org/wm-spec/wm-spec-1.4.html
Comment 3 Matthias Clasen 2015-03-18 19:22:45 UTC
I still think this would be a nice addition to the window menu
Comment 4 Isaac Ge 2015-03-19 08:04:40 UTC
I am working at this feature now.
Comment 5 Isaac Ge 2015-03-19 13:17:59 UTC
Created attachment 299816 [details] [review]
Hi anyone I write a simple patch to implement this feature, I think it can work in theory, but all gnome-shell freezed when I click "move to monitor 1" in the menu... So what is wrong? Thank you!

Of course, you should save all work before try this danger patch!

windowMenu: Add option to move different monitor

The window menu has all those workspace related options, but with multiple monitors, it is much more interesting to quickly move a window 'over' to the other monitor.

Might be a nice addition, and should of course only be shown if there are multiple monitors...

https://bugzilla.gnome.org/show_bug.cgi?id=633994

Signed-off-by: acgtyrant <acgtyrant@gmail.com>
Comment 6 Florian Müllner 2015-03-20 13:55:14 UTC
Review of attachment 299816 [details] [review]:

gnome-shell does not freeze, the patch is simply wrong and crashes the window manager.

Regarding the UI, I'm not convinced that this is how we want to present the option - for workspace, we use directional entries (Move workspace up/down/left/right), I think this would also be the better option for monitors.

::: js/ui/windowMenu.js
@@ +123,3 @@
+          for (var i = 0; i < nMonitors; i++) {
+            item = this.addAction(_("Move to Monitor " + (i + 1)), Lang.bind(this, function(event) {
+              window.move_to_monitor(i);

Careful with closures - "i" has function scope, so it will always have the value nMonitors at the time the closure is called, which is out of range for a monitor index and hits an assertion.
Comment 7 Isaac Ge 2015-03-21 03:03:25 UTC
(In reply to Florian Müllner from comment #6)

> ::: js/ui/windowMenu.js
> @@ +123,3 @@
> +          for (var i = 0; i < nMonitors; i++) {
> +            item = this.addAction(_("Move to Monitor " + (i + 1)),
> Lang.bind(this, function(event) {
> +              window.move_to_monitor(i);
> 
> Careful with closures - "i" has function scope, so it will always have the
> value nMonitors at the time the closure is called, which is out of range for
> a monitor index and hits an assertion.

So I create a closure casually, however it still does not work when I declare variable in that function.

for (var monitorIndex = 0; monitorIndex < nMonitors; monitorIndex++) {
            item = this.addAction(_("Move to Monitor " + monitorIndex), Lang.bind(this, function(event, monitorIndex) {
              window.move_to_monitor(monitorIndex);

 I click the menu item and the log complains that: 

(gnome-shell:16186): Gjs-WARNING **: JS ERROR: Exception in callback for signal: activate: Error: can't convert monitorIndex to an integer
WindowMenu<._buildMenu/item<@resource:///org/gnome/shell/ui/windowMenu.js:125
PopupMenuBase<.addAction/<@resource:///org/gnome/shell/ui/popupMenu.js:467
_emit@resource:///org/gnome/gjs/modules/signals.js:124
PopupBaseMenuItem<.activate@resource:///org/gnome/shell/ui/popupMenu.js:164
wrapper@resource:///org/gnome/gjs/modules/lang.js:169
PopupBaseMenuItem<._onButtonReleaseEvent@resource:///org/gnome/shell/ui/popupMenu.js:125
wrapper@resource:///org/gnome/gjs/modules/lang.js:169

I am confused now, could you advice please...? Thank you!

Of course I know this is not you want to present the option, but I am afraid that I can not go on until I solve this issue.
Comment 8 Florian Müllner 2015-03-21 03:31:05 UTC
(In reply to Isaac Ge from comment #7)
> So I create a closure casually, however it still does not work when I
> declare variable in that function.
> 
> for (var monitorIndex = 0; monitorIndex < nMonitors; monitorIndex++) {
>             item = this.addAction(_("Move to Monitor " + monitorIndex),
> Lang.bind(this, function(event, monitorIndex) {
>               window.move_to_monitor(monitorIndex);
> 
>  I click the menu item and the log complains that: 
> 
> (gnome-shell:16186): Gjs-WARNING **: JS ERROR: Exception in callback for
> signal: activate: Error: can't convert monitorIndex to an integer

That's because the callback is called (in js/ui/popupMenu.js) as:

  menuItem.connect('activate', Lang.bind(this, function (menuItem, event) {
            callback(event);                                                    
        }));

In other words: callback is called with a single parameter, thus the second parameter you are using has the value of undefined, which indeed cannot be converted to a number.

What you can do instead is mirroring the index in a local variable each iteration:

for (let i = 0; i < nMonitors; i++) {
    let monitorIndex = i;
    item = this.addAction(_("Move to Monitor " + monitorIndex), Lang.bind(this,
        function() {
            window.move_to_monitor(monitorIndex);
        }));
Comment 9 Isaac Ge 2015-03-21 13:46:01 UTC
I am afraid that there is not any mutter relative API that move window between some monitors in a special direction...
Comment 10 Florian Müllner 2015-03-21 13:57:19 UTC
There is, it is just not introspected (yet):
https://git.gnome.org/browse/mutter/tree/src/core/screen-private.h#n164
Comment 11 Isaac Ge 2015-03-21 14:53:29 UTC
I write out this new code :

let screen = window.get_screen();
let nMonitors = screen.get_n_monitors();
if (nMonitors > 1) {
  this.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());


  for (let monitorIndex = 0; monitorIndex < nMonitors; monitorIndex++) {
    let monitorInfo = screen.get_monitor_neighbor(monitorIndex, Meta.ScreenDirection.UP)
    if (monitorInfo) {
      item = this.addAction(_("Move to Monitor Up"), Lang.bind(this, function(event) {
        window.move_to_monitor(monitorInfo.number);
      }));
    }
  }
}

However it is difficult to map Mutter native API to JavaScript, the log complains after I rebuild and right-click in a titlebar:

(gnome-shell:21618): Gjs-WARNING **: JS ERROR: TypeError: Meta.Screen.Direction is undefined

I tried `Meta.Screen.Direction.UP` too, it is still undefined. Any idea? Thank you!
Comment 12 Florian Müllner 2015-03-21 15:01:38 UTC
(In reply to Isaac Ge from comment #11)

>     let monitorInfo = screen.get_monitor_neighbor(monitorIndex,
> Meta.ScreenDirection.UP)

That's the correct way to map MetaScreenDirection, once you expose the type to introspection - did you do that?
Comment 13 Isaac Ge 2015-03-22 12:03:53 UTC
(In reply to Florian Müllner from comment #12)

> That's the correct way to map MetaScreenDirection, once you expose the type to introspection - did you do that?

Sorry, but I do not how to "expore the type to introspection"...
Comment 14 Florian Müllner 2015-03-22 13:48:31 UTC
Created attachment 300072 [details] [review]
screen: Add public method to get neighboring monitor

The existing private get_monitor_neighbor() function returns a
MetaMonitorInfo, which is private as well. Add a public wrapper
that returns a monitor index instead, as we do for other public
monitor-related methods.

(In reply to Isaac Ge from comment #13)
> Sorry, but I do not how to "expose the type to introspection"...

Yeah, no worries - attached patch should do the job.
Comment 15 Isaac Ge 2015-03-23 03:22:55 UTC
Created attachment 300107 [details] [review]
windowMenu: Add option to move different monitor

The window menu has all those workspace related options, but with multiple
monitors, it is much more interesting to quickly move a window 'over' to the
other monitor.

Might be a nice addition, and should of course only be shown if there are
multiple monitors...
Comment 16 Florian Müllner 2015-03-23 21:25:38 UTC
Review of attachment 300107 [details] [review]:

Code looks mostly good, thanks!

The commit message needs some cleanup, something like "Might be a nice addition" doesn't really belong there.

::: js/ui/windowMenu.js
@@ +109,3 @@
                 }
                 if (idx < nWorkspaces) {
+                    this.addAction(_("Move to Workspace Down"), Lang.bind(this, function(event) {

Unrelated

@@ +115,3 @@
             }
         }
+        

Trailing whitespace

@@ +117,3 @@
+        
+        let screen = window.get_screen();
+        let nMonitors = screen.get_n_monitors();

Use global.screen
Comment 17 Florian Müllner 2015-03-23 22:03:03 UTC
Review of attachment 300107 [details] [review]:

Code looks mostly good, thanks!

The commit message needs some cleanup, something like "Might be a nice addition" doesn't really belong there.

::: js/ui/windowMenu.js
@@ +109,3 @@
                 }
                 if (idx < nWorkspaces) {
+                    this.addAction(_("Move to Workspace Down"), Lang.bind(this, function(event) {

Unrelated

@@ +115,3 @@
             }
         }
+        

Trailing whitespace

@@ +117,3 @@
+        
+        let screen = window.get_screen();
+        let nMonitors = screen.get_n_monitors();

Use global.screen

@@ +143,3 @@
+          let rightMonitorIndex = screen.get_monitor_neighbor_index(monitorIndex, Meta.ScreenDirection.RIGHT);
+          if (rightMonitorIndex != -1) {
+            this.addAction(_("Move to Monitor Down"), Lang.bind(this, function(event) {

This is also obviously wrong :-)
Comment 18 Isaac Ge 2015-03-24 03:21:58 UTC
Created attachment 300168 [details] [review]
windowMenu: Add option to move different monitor

The window menu has all those workspace related options, but with multiple monitors, it is much more interesting to quickly move a window 'over' to the other monitor.
Comment 19 Florian Müllner 2015-03-24 08:41:27 UTC
Review of attachment 300168 [details] [review]:

The commit message body needs wrapping, otherwise looks good to me now - thanks!
Comment 20 Isaac Ge 2015-03-24 08:56:42 UTC
(In reply to Florian Müllner from comment #19)
> Review of attachment 300168 [details] [review] [review]:
> 
> The commit message body needs wrapping, otherwise looks good to me now thanks!

My English is so poor that I am not sure what is the good commit message... The [guide][1] only mentioned that "Says why the change was made (avoid a gcc warning)" However, is this OK?

> windowMenu: Add option to move different monitor
>
> The existing window menu offers all those workspace motion options, add a option to move different monitors as we do for monitor. 

[1]: https://wiki.gnome.org/GnomeLove/SubmittingPatches#A3._Commit
Comment 21 Florian Müllner 2015-03-24 09:22:39 UTC
(In reply to Isaac Ge from comment #20)
> (In reply to Florian Müllner from comment #19)
> > Review of attachment 300168 [details] [review] [review] [review]:
> > 
> > The commit message body needs wrapping, otherwise looks good to me now thanks!
> 
> My English is so poor that I am not sure what is the good commit message...
> The [guide][1] only mentioned that "Says why the change was made (avoid a
> gcc warning)" However, is this OK?

The text itself was fine, but commit messages are not auto-wrapped, so you need to include line breaks rather than putting everything in a single line:

The window menu has all those workspace related options, but with multiple
monitors, it is much more interesting to quickly move a window 'over' to the other monitor.
Comment 22 Isaac Ge 2015-03-24 09:26:05 UTC
Created attachment 300184 [details] [review]
windowMenu: Add option to move different monitor

The window menu has all those workspace related options, but with multiple
monitors, it is much more interesting to quickly move a window 'over' to the
other monitor.
Comment 23 Florian Müllner 2015-04-14 21:20:36 UTC
Comment on attachment 300184 [details] [review]
windowMenu: Add option to move different monitor

Attachment 300184 [details] pushed as 43fc598 - windowMenu: Add option to move different monitor
Comment 24 Florian Müllner 2015-04-14 21:22:17 UTC
Attachment 300072 [details] pushed as 2e3086e - screen: Add public method to get neighboring monitor