0

I run python 2.7.13 on windows 7. I am creating a window with Gtk (from pygobject 3.18.2).

I am running windows 7 with a custom shell and I am trying to make a toolbar at the bottom of the screen.

I use a grid to divide the window in a top and a bottom part.

The bottom part is always visible. The top part must show above the bottom part on mouse enter and hide on mouse leave without moving the bottom part.

The default positioning of a window uses the top-left corner of the window, but this will cause the bottom part to shift up to the position of the top part when the top part is hidden.

I think I understand that I have to use

set_gravity(Gdk.Gravity.SOUTH_WEST)

to change this behaviour

I do not get errors, but it seems this setting is ignored. The placement of the window is not affected at all.

What am I missing?
Anything wrong in the way I call set_gravity()?
Is set_gravity the right way to achieve this?

I read Set window gravity in PyGObject?, but this question is still not answered

Here is the code I try to get working

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Test")
        self.set_decorated(0)
        self.screen = Gdk.Screen.get_default()
        self.connect("destroy", self.destroy)
        self.connect("enter-notify-event", self.mouseenter)
        self.connect("leave-notify-event", self.mouseleave)

        self.label1 = Gtk.Label("Label1\n    line1\n    line2")
        self.label2 = Gtk.Label("Label2")

        self.label1.set_hexpand(True)
        self.label2.set_hexpand(True)

        self.maingrid = Gtk.Grid()
        self.add(self.maingrid)

        self.maingrid.attach(self.label1, 0, 0, 1, 1)
        self.maingrid.attach(self.label2, 0, 1, 1, 1)

        self.set_gravity(Gdk.Gravity.SOUTH_WEST)  # looks like this is ignored
        print self.get_gravity()

    def mouseleave(self, widget, data=None):
        print "mouse leave"

        self.label1.hide()
        label2_height = self.label2.get_allocation().height
        self.resize(self.screen.width(), label2_height)

    def mouseenter(self, widget, data=None):
        print "mouse enter"

        label1_height = self.label1.get_allocation().height
        label2_height = self.label2.get_allocation().height
        self.resize(self.screen.width(), label1_height + label2_height)

        self.label1.show()

        # Here I expect label2 to stay where it is at the bottom of the screen and label1 to be drawn above label2.
        # But label2 is pushed down to make space for label1
        # (normal behaviour if Gdk.Gravity.SOUTH_WEST is not set)

    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        Gtk.main_quit()

win = MyWindow()
win.show_all()
win.label1.hide()

height = win.label2.get_allocation().height
win.resize(win.screen.width(), height)

#win.move(0, win.screen.height())           # I expect this to place the window at the bottom of the screen
                                            # if Gdk.Gravity.SOUTH_WEST is set, but it is placed offscreen
                                            # (normal behaviour if Gdk.Gravity.SOUTH_WEST is not set)

win.move(0, win.screen.height() - 200)      # shift it up 200 pixels to see what is happening


Gtk.main()

Here is a working version where I move the window to it's proper position after resizing. Moving the window makes the window flicker and it also generates the leave-notify-event and the enter-notify-event.

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Test")
        self.set_decorated(0)
        self.screen = Gdk.Screen.get_default()
#        self.set_gravity(Gdk.Gravity.SOUTH_WEST)
        self.connect("destroy", self.destroy)
        self.connect("enter-notify-event", self.mouseenter)
        self.connect("leave-notify-event", self.mouseleave)

        self.label1 = Gtk.Label("Label1\n    line1\n    line2")
        self.label2 = Gtk.Label("Label2")

        self.label1.set_hexpand(True)
        self.label2.set_hexpand(True)

        self.maingrid = Gtk.Grid()
        self.add(self.maingrid)

        self.maingrid.attach(self.label1, 0, 0, 1, 1)
        self.maingrid.attach(self.label2, 0, 1, 1, 1)
        self.ismoving = 0

    def mouseleave(self, widget, data=None):
        print "mouse leave"

        if self.ismoving:
            print "window is moving"
        else:
            self.label1.hide()
            label2_height = self.label2.get_allocation().height
            self.resize(self.screen.width(), label2_height)
            self.move(0, self.screen.height() - label2_height)

    def mouseenter(self, widget, data=None):
        print "mouse enter"

        if self.ismoving:           # moving the window generates a leave-notify-event and a enter-notify-event
            self.ismoving = 0       # ignore these events when moving the window
        else:
            self.ismoving = 1

            label1_height = self.label1.get_allocation().height
            label2_height = self.label2.get_allocation().height
            self.resize(self.screen.width(), label1_height + label2_height)

            self.move(0, self.screen.height()-label1_height - label2_height)

            self.label1.show()

    def destroy(self, widget, data=None):
        print "destroy signal occurred"
        Gtk.main_quit()

win = MyWindow()
win.show_all()
win.label1.hide()

height = win.label2.get_allocation().height
win.resize(win.screen.width(), height)
win.move(0, win.screen.height() - height)


Gtk.main()

Based on AlexB's comment i assume my code is correct, but it is not working for me. I don't see any reason why it will not run under python 2. Maybe there is an issue with the window manager. I'll investigate

Did anyone succesfully use set_gravity() on windows?

bbuggy
  • 25
  • 7
  • 1
    Running this against Python 3 under MSYS2 seems to produce the desired result, Py2 v Py3 shouldn't make a different here but any particular reason for starting a new project in Python 2? – Zander Brown Jul 07 '17 at 12:41
  • 1
    @AlexB I am using Eventghost as my shell. Eventghost is running on python 2.7 . I like to keep things simple and use one language – bbuggy Jul 07 '17 at 13:08

1 Answers1

0

Documentation indicates it may or may not work, depending on Window Manager. It doesn't for me on Xubuntu 18.04

gerardw
  • 5,822
  • 46
  • 39