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 596432 - Add a calendar pop-down to the clock
Add a calendar pop-down to the clock
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Owen Taylor
gnome-shell-maint
Depends on:
Blocks: 582058 gnome-shell-2-28
 
 
Reported: 2009-09-26 15:10 UTC by Owen Taylor
Modified: 2009-10-01 20:57 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add a calendar pop-down to the clock (12.63 KB, patch)
2009-09-30 14:21 UTC, Owen Taylor
committed Details | Review
testcommon.css: Don't theme all buttons (1.83 KB, patch)
2009-09-30 14:22 UTC, Owen Taylor
committed Details | Review
Add scroll-wheel support to the calendar (2.48 KB, patch)
2009-10-01 19:23 UTC, Owen Taylor
committed Details | Review
Fixes for Calendar widget (3.62 KB, patch)
2009-10-01 20:19 UTC, Owen Taylor
committed Details | Review

Description Owen Taylor 2009-09-26 15:10:30 UTC
This is related to bug 582058 but instead of covering getting all the functionality of the gnome-panel clock back, is about a quick fix for 2.28.0.

For 2.28, we should add a calendar popdown to the clock on click, it should look something like:

     Su Mo Tu We Th Fr Sa
           1  2  3  4  5
     6  7  8  9 10 11 12
    13 14 15 16 17 18 19
    20 21 22 23 24 25 26
    27 28 29 30

We could just use GtkCalendar for this, but it's going to look better
and if we rewrite it as Shell Chrome and it shouldn't take too long
to do that.
Comment 1 Owen Taylor 2009-09-26 15:13:13 UTC
(the above was supposed include the current date (day month year? just month year?) above the "calendar page"

I have a start on this now - a calendar implemented but not yet hooked up to the clock. It's based on the nbtk-introduction branch with NbtkTable so I need to sort that out.
Comment 2 Owen Taylor 2009-09-30 14:21:03 UTC
Created attachment 144404 [details] [review]
Add a calendar pop-down to the clock

Here's a patch implementing the calendar popdown. It depends upon the shell-toolkit
branch including the patches in bug 596811 to add StTable.

Some things that might be debatable:

 - It isn't menu-like - it doesn't grab the keyboard and pointer when up;
   this is meant to allow someone to interact with an app while it is up.

 - Not sure the slide-in adds anything, though it's consistent with what
   LookingGlass does.

 - To get an input-region-but-no-struts actor, doing:

        Main.chrome.actor.add_actor(this.actor);
        Main.chrome.addInputRegionActor(this.actor);

   is definitely a bit of a hack. I wasn't quite sure about how to best rearrange
   all the chrome functions to enable this more cleanly.
   It maybe should be chrome.addActor(actor, { options: ... }) ?
Comment 3 Owen Taylor 2009-09-30 14:22:02 UTC
Created attachment 144405 [details] [review]
testcommon.css: Don't theme all buttons

This patch isn't needed for the calendar popdown, but the test case
looks a bit ugly without it.
Comment 4 Owen Taylor 2009-10-01 19:23:55 UTC
Created attachment 144533 [details] [review]
Add scroll-wheel support to the calendar

Make the calendar reactive and handle scroll events to change the month.
(GtkCalendar and hence the old gnome-panel calendar supported this and
it is apparently a handy way to flip through months.)

The padding is moved from the CalenderPopup to the Calendar so that the
scroll region extends all the way to the edge of the popup.
Comment 5 Dan Winship 2009-10-01 19:36:53 UTC
Comment on attachment 144404 [details] [review]
Add a calendar pop-down to the clock

>+#calendarPopup {
>+    border-radius: 5px;

It looks odd IMHO to have rounded borders on the top.

>+    background: rgba(0,0,0,0.9);

likewise, it just seems distracting/inconvenient to be able to see windows through the calendar. 

>+        let back = new St.Button({ label: "<", style_class: 'calendar-change-month'  });

< / > seem a little too pointy. I was going to suggest \u2039 / \u203A (single guillemets), which are closer to GtkCalendar, but they're too small, and my attempts to fiddle with the CSS didn't seem to do anything...

>+        iter.setSeconds(0); // Leap second protection. Hah!

If we're actually worrying about leap seconds, then every place that uses MSECS_IN_DAY is potentially wrong. Eg, starting at 00:00:00 on a day with a leap day and doing

>+            iter.setTime(iter.getTime() + MSECS_IN_DAY);

will set iter to 24:59:60 on the same day rather than 00:00:00 tomorrow.

In this particular case, since we don't care which dates we're looking at, just that they're valid dates, can't you do:

    for (let i = 0; i < 7; i++) {
        iter.setDate(i + 1);
        ...

? (This doesn't help with figuring out the actual days to show later on though)

>+    _update: function() {
>+        this._dateLabel.text = this.date.toLocaleFormat("%B %Y");

should use this._headerFormat

>+        for (let i = 8; i < children.length; i++)

"8"? srsly? (Yes, I know the comment I didn't quote explains it, but it seems pretty fragile.)

>+        Main.chrome.actor.add_actor(this.actor);
>+        Main.chrome.addInputRegionActor(this.actor);

You're not supposed to fiddle with Main.chrome.actor behind its back, and the fact that this is the only way to do what you wanted to do here should be considered a bug/missing feature in chrome.

I think

    Main.chrome.addActor(this.actor, null);
    Main.chrome.addInputRegionActor(this.calendar.actor);

would work without breaking abstraction barriers or changing chrome.

>+++ b/tests/interactive/calendar.js

>+const Gettext_gtk20 = imports.gettext.domain('gtk20');

don't need that there.
Comment 6 Owen Taylor 2009-10-01 20:14:31 UTC
(In reply to comment #5)
> (From update of attachment 144404 [details] [review])
> >+#calendarPopup {
> >+    border-radius: 5px;
> 
> It looks odd IMHO to have rounded borders on the top.

I tried sliding it under the panel a few pixels to get rounded corners just at the bottom and it just looked weird.

> >+    background: rgba(0,0,0,0.9);
> 
> likewise, it just seems distracting/inconvenient to be able to see windows
> through the calendar. 

I think I'll leave that to the graphics artists to improve. This is apparently the same as we're using in the Fedora 12 notification bubble theme which is supposed to match.

> >+        let back = new St.Button({ label: "&lt;", style_class: 'calendar-change-month'  });
> 
> < / > seem a little too pointy. I was going to suggest \u2039 / \u203A (single
> guillemets), which are closer to GtkCalendar, but they're too small, and my
> attempts to fiddle with the CSS didn't seem to do anything...

Hmm, trying to get small subscript characters to look not like small subscripts without breaking the overall spacing is going to be hard. But:

 .calendar-change-month {
     padding: 2px;
+    font-size: 200%;
 }

seems to work fine (was worried that you were seeing some CSS bug)

> >+        iter.setSeconds(0); // Leap second protection. Hah!
> 
> If we're actually worrying about leap seconds, then every place that uses
> MSECS_IN_DAY is potentially wrong. Eg, starting at 00:00:00 on a day with a
> leap day and doing
> 
> >+            iter.setTime(iter.getTime() + MSECS_IN_DAY);
> 
> will set iter to 24:59:60 on the same day rather than 00:00:00 tomorrow.

Oh, I knew there was a reason I used to have a iter.setHours(12); in there too. I'll add it back. (Yes, worrying about leap seconds to start with is ridiculous) 

> In this particular case, since we don't care which dates we're looking at, just
> that they're valid dates, can't you do:
> 
>     for (let i = 0; i < 7; i++) {
>         iter.setDate(i + 1);
>         ...

setDate(32) isn't going to work. setDate() needs to set a valid date.

> ? (This doesn't help with figuring out the actual days to show later on though)
> 
> >+    _update: function() {
> >+        this._dateLabel.text = this.date.toLocaleFormat("%B %Y");
> 
> should use this._headerFormat

Hmm, should have actually found local with the reversed and tested. (Did that now.) Fixed.

> >+        for (let i = 8; i < children.length; i++)
> 
> "8"? srsly? (Yes, I know the comment I didn't quote explains it, but it seems
> pretty fragile.)

OK, fixed with a:

+        // All the children after this are days, and get removed when we update the calendar
+        this._firstDayIndex = this.actor.get_children().length;

in the _init().
 
> >+        Main.chrome.actor.add_actor(this.actor);
> >+        Main.chrome.addInputRegionActor(this.actor);
> 
> You're not supposed to fiddle with Main.chrome.actor behind its back, and the
> fact that this is the only way to do what you wanted to do here should be
> considered a bug/missing feature in chrome.
> 
> I think
> 
>     Main.chrome.addActor(this.actor, null);
>     Main.chrome.addInputRegionActor(this.calendar.actor);
> 
> would work without breaking abstraction barriers or changing chrome.

Doesn't look like it to me - the actor will get tracked twice as far as I can see. OK if I leave this like this for the moment and file a bug for addActor(actor, { option: .. })? I'll try to get to that soon, but not today, tomorrow.

> >+++ b/tests/interactive/calendar.js
> 
> >+const Gettext_gtk20 = imports.gettext.domain('gtk20');
> 
> don't need that there.

Ah yes, as you can see the whole calendar was originally developed in that test case. Fixed.
Comment 7 Owen Taylor 2009-10-01 20:19:05 UTC
Created attachment 144540 [details] [review]
Fixes for Calendar widget

Miscellaneous fixes from review:

- Distribute calendar.js and the interactive test
- Make the pointless protection against leap seconds actually work
  by starting in the middle of the day so that forward/back always
  move a day.
- Use a variable instead of an inline '8' to know where to start
  when removing old day actors.
- Remove a stray comment from the test
Comment 8 Dan Winship 2009-10-01 20:42:27 UTC
>  .calendar-change-month {
>      padding: 2px;
> +    font-size: 200%;
>  }
> 
> seems to work fine (was worried that you were seeing some CSS bug)

probably I was using the wrong syntax...

> > In this particular case, since we don't care which dates we're looking at, just
> > that they're valid dates, can't you do:
> > 
> >     for (let i = 0; i < 7; i++) {
> >         iter.setDate(i + 1);
> >         ...
> 
> setDate(32) isn't going to work. setDate() needs to set a valid date.

right, but it never does setDate(32). It does setDate(1) through setDate(7). That's what I meant about "since we don't care which dates we're looking at". Since the 1st through 7th exist in every month, we can just look at those.

> > ? (This doesn't help with figuring out the actual days to show later on though)

that comment still applies; if you redraw the calendar at exactly midnight when there is a day with a leap second visible, you'll lose. (The correct response to this may be "shrug".)

> > I think
> > 
> >     Main.chrome.addActor(this.actor, null);
> >     Main.chrome.addInputRegionActor(this.calendar.actor);
> > 
> > would work without breaking abstraction barriers or changing chrome.
> 
> Doesn't look like it to me - the actor will get tracked twice as far as I can
> see.

if you pass null for the second arg to addActor then it doesn't call trackActor.
Comment 9 Owen Taylor 2009-10-01 20:49:09 UTC
Attachment 144533 [details] pushed as 061a2cf - Add scroll-wheel support to the calendar
Attachment 144540 [details] pushed as afb3b1e - Fixes for Calendar widget
Comment 10 Owen Taylor 2009-10-01 20:57:30 UTC
(In reply to comment #8)

> > > In this particular case, since we don't care which dates we're looking at, just
> > > that they're valid dates, can't you do:
> > > 
> > >     for (let i = 0; i < 7; i++) {
> > >         iter.setDate(i + 1);
> > >         ...
> > 
> > setDate(32) isn't going to work. setDate() needs to set a valid date.
> 
> right, but it never does setDate(32). It does setDate(1) through setDate(7).
> That's what I meant about "since we don't care which dates we're looking at".
> Since the 1st through 7th exist in every month, we can just look at those.

Ah, yeah, sure.

> > > ? (This doesn't help with figuring out the actual days to show later on though)
> 
> that comment still applies; if you redraw the calendar at exactly midnight when
> there is a day with a leap second visible, you'll lose. (The correct response
> to this may be "shrug".)

I think it's fine with the current code. We start off at:

 12:xy:00

and step days from there. You'd have to go past ~40,000 leap seconds to hit the wrong day boundary. (And there's only been about a dozen leap seconds total, iirc)

> > > I think
> > > 
> > >     Main.chrome.addActor(this.actor, null);
> > >     Main.chrome.addInputRegionActor(this.calendar.actor);
> > > 
> > > would work without breaking abstraction barriers or changing chrome.
> > 
> > Doesn't look like it to me - the actor will get tracked twice as far as I can
> > see.
> 
> if you pass null for the second arg to addActor then it doesn't call
> trackActor.

OK, well, count it as confusing at least. :-).  I filed bug 597044 and added a reference to it in the code.