[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: visibility?
From:       Rik Hemsley <rik () kde ! org>
Date:       2000-03-07 20:53:46
[Download RAW message or body]

#if Christopher Molnar
> OK, if you have some patience give me an overview of what needs to happen
> and I'll ask questions as needed. (A pointer to the right area of code
> would be nice as well).

Here we go...

I'm sending this to kde-devel so that people can see that the
app-starting indicator is on its way and simply needs some code
writing.

Brief explanation:

        When KApplication::setTopWidget() is called, various
        properties are set on the toplevel widget (window). One of
        these is the WM_COMMAND property. This has two parts, res_name
        and res_class. res_name is set from argv[0] (so we know the
        name of the binary) and res_class is simply set to "toplevel" -
        we don't need that.

        (BTW, thanks to whomever cleaned up that code :)

        Now, when we launch an app, we want to pass the name of
        the binary to kicker. kicker will notify the user that
        the app is starting by _immediately_ creating a taskbar
        entry for that app.

        When the application sets a toplevel widget (window),
        kwin will pass the name of the app (found in
        WM_COMMAND -> res_name) to kicker. kicker will then
        replace the 'app starting' indication with a real taskbar
        entry.

        kicker already creates taskbar entries when an app is
        mapped. So all that needs to be done there is to remove
        the 'app starting' indicator.

        The 'app starting' indicator, as I said earlier, should
        be a taskbar entry. This is logical, it's what the user
        expects. The thing that isn't what they expect is that
        there is no accompanying window. For this reason the
        taskbar entry should be marked in some way to make this
        clear. I suggest the 'white gauze' effect as seen in Window
        Maker and over toolbar buttons. Feel free to do spinning
        cogs or something else if you wish, but remember that
        animations eat bandwidth when you're running X remotely,
        so this would not be the best solution.

Step 1: Find out how applications are being launched.

        KDE applications should never launch apps themselves with
        exec() or similar, they should be using the support in kdelibs.

        You need to know whether there is more than one mechanism
        that is being used. When I did this before I just assumed
        that all apps used krun (kio/krun.*) to launch. This might
        not be the case, so that simply needs checking.

        You may also want to keep track of the pids of apps you
        exec and notice when they die. More on this in a bit...

Step 2: Edit kicker's taskbar code.

        You need to receive DCOP signals called:
          'clientStarted(QString, int)',
          'clientMapped(QString)' and
          'clientDied(int)'

        The first (clientStarted()) will be sent by KRun when it
        calls exec().

        You should create an 'app starting' taskbar entry here,
        using the name you are passed in the first parameter.

        The second parameter is the pid of the process that was
        started. You must remember this so that when the process
        exits you can remove the taskbar entry.

        You may say, "Well, I can remove the entry when the window
        goes away" - see the discussion on buggy clients later
        for the reasons why.

        The second (clientMapped()) will be sent by kwin whenever 
        it sees a new window.

Step 3: Edit krun (and anywhere else you find code that launches apps).
        
        You need to emit a signal via DCOP, that is directed to kicker.
        
        Something like this...

        dcopClient->send(
          "kicker",
          "taskbar/something",
          "clientStarted(QString)",
          nameOfAppBinary,
          pid
        );

        You then need to make sure you are notified when the process
        exits, so don't lose that pid.

Step 4: Edit kwin
        
        Again you need to emit a signal via DCOP, that is directed to kicker.
        
        Something like this...

        dcopClient->send(
          "kicker",
          "taskbar/something",
          "clientMapped(QString)",
          WM_CLASS -> res_name
        );

        WM_CLASS is set in kapp.cpp and contains argv[0] and "toplevel".

        Within WM_CLASS, res_name contains argv[0] and res_class
        contains "toplevel".

Final thoughts...

You may wonder how this will work with 'legacy' apps. Well the fact is,
most X11 apps already set WM_COMMAND. Only very few apps do not set
this property. Examples include Tk apps (though that's generally because
the author didn't do it) and KDE 1 apps.

So if some apps don't set WM_COMMAND, how do we know when they have
mapped ? The answer is, we don't. I can't see a way to be sure, and
if we can't be sure, we shouldn't mess, as we'll just get into
trouble.

How to fix this ? You can't, completely.

You can, however, take notes from Window Maker.

krun can be notified when the binary it has exec()'ed has died.
When this happens, it send a clientDied(pid) DCOP signal to kicker.
If kicker finds a taskbar entry with matching associated pid, it
simply removes it.

The upshot of all of this is that a buggy client will create a
taskbar entry which looks permanently like it is starting up.

We can remedy the situation further by using .desktop files to our
advantage. Because we ship KDE with a set of .desktop files for legacy
apps, we can identify some common legacy apps that are buggy (do not
set WM_COMMAND) and mention that fact in their .desktop file.

If krun is 'running a .desktop file' (I believe it does this ?) then
it can simply avoid sending the clientStarted() signal to kicker.
I think this might be a good solution. Any other suggestions are
welcome.

It's also possible that we kicker could get the info from the related
.desktop file itself. I think it's ksycoca it would need to chat
with.

Any questions ? We can take this off-list now if there are no issues
that everyone needs to hear about.

Rik

-- 
Stop waiting for Godot.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic