Page 1 of 1

[Solved] Cannot get the desktop window

PostPosted: Wed May 23, 2018 2:53 am
by hika
I can either create a desktop object or a toolkit object, but if I try to get the desktop window, I get None as a result. What is going wrong?

Code: Select all   Expand viewCollapse view
context = uno.getComponentContext()
smgr = context.ServiceManager
desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', context)
desktopwindow = desktop.getContainerWindow()


Code: Select all   Expand viewCollapse view
context = uno.getComponentContext()
smgr = context.ServiceManager
toolkit = smgr.createInstance('com.sun.star.awt.Toolkit')
desktopwindow = toolkit.getDesktopWindow()


I tried both in openoffice and in libreoffice. Both with and without a document open.

Hika

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 10:05 am
by hubert lambert
Hi,

Afaik, the Desktop is a sort of abstract service that serves mainly as a frame containers. It has no window but every frame it contains does (as frames bind component to window).
When there is no opened document, the "current component" is the so-called start module, and you can access its component or container window throught its frame reference (no controller here) :

Code: Select all   Expand viewCollapse view
    startmodule = XSCRIPTCONTEXT.getDocument()
    window = startmodule.Frame.ComponentWindow)

When a document is opened, it is most of the time loaded in the start module window, thus making a "desktop window" meaningless.

Regards.

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 12:21 pm
by hika
I follow your reasoning and it sounds logical. Does this mean that "toolkit.getDesktopWindow()" is an old relic? Still there but no longer doing anything.

I was looking, because if I build a dialog embedded in a frame/window set: "unocomponent.createPeer(toolkit, None)" gives an error "unsatisfied query for interface of type com.sun.star.XView". Setting the peer to its own window works, but subsequently executing the dialog (through the XDialog interface in the window, executing it in the dialog no longer works) does not properly make it modal as it is modal to itself.
I will see if I can use your suggestion as a peer and if that will properly make it modal.

Hika

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 4:15 pm
by hubert lambert
hika wrote:Does this mean that "toolkit.getDesktopWindow()" is an old relic? Still there but no longer doing anything.

You should be right, as the Dev's Guide states that:
The name of this service originates at StarOffice 5.x, where all document windows were embedded into a common application window that was occupied by the StarOffice desktop, mirroring the Windows desktop. The root frame of this hierarchy was called the desktop frame. The name of this service and the interface name com.sun.star.frame.XDesktop were kept for compatibility reasons.

hika wrote:I was looking, because if I build a dialog embedded in a frame/window set: "unocomponent.createPeer(toolkit, None)" gives an error "unsatisfied query for interface of type com.sun.star.XView". Setting the peer to its own window works, but subsequently executing the dialog (through the XDialog interface in the window, executing it in the dialog no longer works) does not properly make it modal as it is modal to itself.

I'm not sure to fully understand. If you're not sure about the parent window, you can always pass the current frame component window:
Code: Select all   Expand viewCollapse view
unocomponent.createPeer(toolkit, desktop.CurrentFrame.ComponentWindow)

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 6:37 pm
by hika
It starts, but it breaks the binding between the dialog and its window/frame. So I guess that, if you want to embed a dialog in a window/frame set, setting that window as peer is mandatory.

What I mean by it not being properly modal is that executing it does not, as with a ordinary dialog, block access to the window from where you started it. I guess I have to find a way to make the dialog window a proper child of the executing window. It already, if you in its descriptor set the WindowServiceName to "modaldialog", takes over the com.sun.star.awt.XDialog(2) interfaces.
It is somewhere, but finding it ...

Hika

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 6:48 pm
by hubert lambert
It would be more convenient with a full example...

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 7:04 pm
by hika
It's a complex framework with a lot of subroutines, but this is the present __init__ for my unoForm class
It can create at present 5 types of dialogs/forms. From a classic dialog up to a window/frame set without a dialog model
Code: Select all   Expand viewCollapse view
class UnoForm(UnoContainer, UnoTopFormListner, UnoBase):
    def __init__(self, ubase, name, **kwargs):
        UnoBase.__init__(self, ubase)
        self.initializing = True
        self.resizing = False
        self.args = kwargs
        self.log_settings = self.get_opt('log_settings', bool, False)
        self.log_object_tree = self.get_opt('log_object_tree', bool, False)
        self.log_size_tree = self.get_opt('log_size_tree', bool, False)
        self.log_listeners = self.get_opt('log_listeners', bool, False)
        self.form = self
        self.parent = self
        self.name = name
        self.datavalue = None
        self.properties = {'level': 0, 'form_defaults': {}, 'font': {}}
        self._init_properties(self, '--form_defaults--', '', 'form_defaults')
        self._init_properties(self, '', None, 'form')
        self._init_properties(self, '--possize--', self.uc_orientation.HORIZONTAL, 'form')
        self._init_properties(self, '--possize--', self.uc_orientation.VERTICAL, 'form')
        self.controls = {}
        self.data_controls = {}
        self.datavalues = {}
        self.tab_order = []
        self.containers = {self.name: self}
        self.datavalues['size_factor'] = Value(self, 'size_factor',
                    self.uno.uc_datatype.PERCENT,
                    self.properties['form_defaults']['size_factor'],
                    self.set_size_factor)
        if self.has_objmode('hasmodel'): # Create Model/Component
            self.implementation = 'UnoDialogControl'
            self.model = self.uno.get_service("awt.UnoControlDialogModel")
            self.model.Name = name
            self.model.Sizeable = True
            self.model.Closeable = True
            for k, v in self.get_opt('model', dict, {}).items():
                self.set_model_property(k, v)

            if self.has_objmode('hasframe'):
                self.model.Decoration = False

            self.properties['dialogmodel'] = 'UnoControlDialogModel'
            self.unocomponent = self.uno.get_service("awt.UnoControlDialog")
            self.unocomponent.setModel(self.model)
            #~ self.uno.list_capabilities(self.unocomponent)

        if self.has_objmode('haswindow'): # Create Window
            self.window = self.uno.get_toolkit().createWindow(self.get_descriptor())
            self.dialog = self.window
            if self.has_objmode('hasframe'): # Create Frame
                self.frame = self.uno.get_service("frame.Frame")
                self.frame.initialize(self.window)
                self.frame.setCreator(self.uno.desktop)
                self.frame.setName(name)
                self.uno.desktop.getFrames().append(self.frame)

        if self.has_objmode('hasmodel'): # Bind the Model
            if not self.has_objmode('hasframe'):
                self.dialog = self.unocomponent

            #~ self.uno.list_capabilities(self.uno.desktop.getCurrentFrame().getContainerWindow())
            #~ self.uno.list_capabilities(self.window)
            if not self.has_objmode('haswindow'): # to the Desktop
                self.unocomponent.createPeer(self.uno.get_toolkit(), None)

            elif self.has_objmode('ismodal'):
                self.unocomponent.createPeer(self.uno.get_toolkit(), self.window)

            else: # to the Window
                self.unocomponent.createPeer(self.uno.get_toolkit(), self.window)

            self.uno.list_capabilities(self.window)
            self.__init_component__(name)

        self.listeners = {'top': [], 'window': [], 'focus': [], 'key': [], 'mouse': []}
        self.set_visible(False)
        self._set_listener_proc()
        self.add_listener('all', self)
        self.load_datavalues(**self.get_opt('datavalues', (dict, Record), {}))
        if self._init_container(True):
            self.init_minsize()

        self.set_caption()
        self.set_font(**self.properties['font'])
        self.set_colors()
        self.set_properties()

    def get_descriptor(self):
        descriptor = self.uno.get_struct("awt.WindowDescriptor")
        #~ buttondialog, tabdialog, dialog, modaldialog, modelessdialog
        #~ framewindow, window, workwindow
        if self.has_objmode('ismodal'):
            descriptor.Type = self.ue_winclass.MODALTOP
            descriptor.WindowServiceName = "modaldialog"

        elif self.has_objmode('hasmodel'):
            descriptor.Type = self.ue_winclass.TOP
            descriptor.WindowServiceName = "modelessdialog"

        else:
            descriptor.Type = self.ue_winclass.TOP
            descriptor.WindowServiceName = "dialog"

        descriptor.ParentIndex = -1
        #~ descriptor.Parent = 0
        descriptor.WindowAttributes = self.properties['winattr']
        return descriptor



Maybe I must do something with the Parent in the window descriptor

Re: Cannot get the desktop window

PostPosted: Wed May 23, 2018 8:32 pm
by hika
Yes! Setting descriptor.Parent = self.uno.desktop.getCurrentFrame().getContainerWindow() makes it truly modal. Only the minimize and maximize buttons then disappear while the dialog stays sizeable. Funny.
Obviously the descriptor.Parent for a window has a similar function as the peer for dialogs and controls.