Merge lp:~jeremywootten/audience/fix-1627167-black-bars into lp:~audience-members/audience/trunk

Proposed by Jeremy Wootten
Status: Rejected
Rejected by: Jeremy Wootten
Proposed branch: lp:~jeremywootten/audience/fix-1627167-black-bars
Merge into: lp:~audience-members/audience/trunk
Diff against target: 239 lines (+120/-11)
2 files modified
src/Widgets/Player/PlayerPage.vala (+6/-7)
src/Window.vala (+114/-4)
To merge this branch: bzr merge lp:~jeremywootten/audience/fix-1627167-black-bars
Reviewer Review Type Date Requested Status
Audience Members Pending
Review via email: mp+321761@code.launchpad.net

Description of the change

This branch addresses a number of problems relating to the display and sizing of videos.

* Black bars around video are eliminated. Note however that resizing by drag and drop, which does not maintain aspect ratio because of a window manager bug, can now result in parts of the video being truncated.

* Implement fixed aspect ratio resizing using Ctrl-Scroll or the keyboard.

* Make sure Welcome Page is always correct size when returning from resized, maximised or minimized window.

* Videos start at their native size and a minimum size is applied

* Implement F11 to toggle fullscreen

* Unmaximise and unfullscreen return to correct window size

* Closing the window while a video is playing no longer results in a segfault

To post a comment you must log in.
Revision history for this message
Jeremy Wootten (jeremywootten) wrote :

This will be resubmitted as separate smaller branches after migration to github.

Unmerged revisions

740. By Jeremy Wootten

Fix segfault when closing while playing

739. By Jeremy Wootten

Resume at same size

738. By Jeremy Wootten

Implement F11 to toggle fullscreen

737. By Jeremy Wootten

Implement keyboard resizing with fixed aspect ratio

736. By Jeremy Wootten

Implement Ctrl-Scroll resizing with constant aspect ratio

735. By Jeremy Wootten

Handle player size change in Window; Fix size of Welcome Page

734. By Jeremy Wootten

Remove black borders

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Widgets/Player/PlayerPage.vala'
2--- src/Widgets/Player/PlayerPage.vala 2016-11-02 23:59:41 +0000
3+++ src/Widgets/Player/PlayerPage.vala 2017-04-03 18:18:46 +0000
4@@ -11,6 +11,7 @@
5 public class PlayerPage : Gtk.EventBox {
6 public signal void unfullscreen_clicked ();
7 public signal void ended ();
8+ public signal void aspect_changed (int width, int height);
9
10 public GtkClutter.Embed clutter;
11 private Clutter.Actor video_actor;
12@@ -78,16 +79,14 @@
13 var aspect_ratio = ClutterGst.Aspectratio.@new ();
14 #endif
15 ((ClutterGst.Aspectratio) aspect_ratio).paint_borders = false;
16+ ((ClutterGst.Aspectratio) aspect_ratio).fill_allocation = true;
17 ((ClutterGst.Content) aspect_ratio).player = playback;
18- /* Commented because of a bug in the compositor
19+
20 ((ClutterGst.Content) aspect_ratio).size_change.connect ((width, height) => {
21- double aspect = ((double) width)/((double) height);
22- var geometry = Gdk.Geometry ();
23- geometry.min_aspect = aspect;
24- geometry.max_aspect = aspect;
25- ((Gtk.Window) get_toplevel ()).set_geometry_hints (get_toplevel (), geometry, Gdk.WindowHints.ASPECT);
26+ set_size_request (width / 3, height / 3); // Set minimum video size
27+ aspect_changed (width, height); // notify window
28 });
29- */
30+
31 video_actor.content = aspect_ratio;
32
33 video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0));
34
35=== modified file 'src/Window.vala'
36--- src/Window.vala 2017-01-25 22:40:27 +0000
37+++ src/Window.vala 2017-04-03 18:18:46 +0000
38@@ -22,6 +22,9 @@
39 */
40
41 public class Audience.Window : Gtk.Window {
42+ private const int DEFAULT_WIDTH = 1000;
43+ private const int DEFAULT_HEIGHT = 680;
44+
45 private Gtk.Stack main_stack;
46 private Gtk.HeaderBar header;
47 private PlayerPage player_page;
48@@ -33,8 +36,9 @@
49 private NavigationButton navigation_button;
50 private ZeitgeistManager zeitgeist_manager;
51 private Gtk.SearchEntry search_entry;
52-
53-
54+ private int added_height; // The amount by which the window height exceeds the player page size when aspect ratio correct.
55+ private double aspect_ratio;
56+ private Gtk.Allocation last_video_allocation;
57 // For better translation
58 const string navigation_button_welcomescreen = N_("Back");
59 const string navigation_button_library = N_("Library");
60@@ -50,7 +54,8 @@
61 zeitgeist_manager = new ZeitgeistManager ();
62 window_position = Gtk.WindowPosition.CENTER;
63 gravity = Gdk.Gravity.CENTER;
64- set_default_geometry (1000, 680);
65+ set_initial_size ();
66+ last_video_allocation = {0, 0};
67
68 header = new Gtk.HeaderBar ();
69 header.set_show_close_button (true);
70@@ -130,6 +135,24 @@
71 app_notification.visible = true;
72 });
73
74+ player_page.aspect_changed.connect ((w, h) => {
75+ aspect_ratio = (double)h / (double)w;
76+ /* Initiate the video playback at natural size. */
77+ added_height = get_allocated_height () - player_page.get_allocated_height ();
78+ resize (w, h + added_height);
79+#if 0
80+ /* Not currently included because a bug in the compositor prevents maintaining the
81+ * aspect ratio on drag resizing.
82+ * Note that using keyboard or scroll now maintains aspect ratio.
83+ */
84+ var geometry = Gdk.Geometry ();
85+ double aspect = ((double) width)/((double) height);
86+ geometry.min_aspect = aspect;
87+ geometry.max_aspect = aspect;
88+ set_geometry_hints (this, geometry, Gdk.WindowHints.ASPECT | Gdk.WindowHints.MIN_SIZE);
89+#endif
90+ });
91+
92 alert_view = new Granite.Widgets.AlertView ("", "", "");
93 alert_view.get_style_context ().add_class (Gtk.STYLE_CLASS_DIM_LABEL);
94 alert_view.set_vexpand (true);
95@@ -205,6 +228,14 @@
96 header.visible = !player_page.fullscreened;
97 }
98
99+ var flags = (Gdk.WindowState.FULLSCREEN | Gdk.WindowState.MAXIMIZED | Gdk.WindowState.ICONIFIED);
100+ if ((flags & e.changed_mask) > 0 &&
101+ (flags & e.new_window_state) == 0 &&
102+ main_stack.get_visible_child () == welcome_page) {
103+
104+ set_initial_size (); //make sure Welcome Page is default size.
105+ }
106+
107 /*/ FIXME: Remove comments once gala bug is fixed: https://bugs.launchpad.net/gala/+bug/1602722
108 if (Gdk.WindowState.MAXIMIZED in e.changed_mask) {
109 bool currently_maximixed = Gdk.WindowState.MAXIMIZED in e.new_window_state;
110@@ -216,6 +247,16 @@
111
112 return false;
113 });
114+
115+ scroll_event.connect (on_scroll_event);
116+
117+ delete_event.connect (() => {
118+ if (player_page.playing) {
119+ /* This prevents a segmentation fault and allows proper shutdown of application */
120+ navigate_back ();
121+ }
122+ return false;
123+ });
124 }
125
126 /** Returns true if the code parameter matches the keycode of the keyval parameter for
127@@ -248,7 +289,7 @@
128 player_page.next_audio ();
129 } else if (match_keycode (Gdk.Key.s, keycode)) {
130 player_page.next_text ();
131- } else if (match_keycode (Gdk.Key.f, keycode)) {
132+ } else if (match_keycode (Gdk.Key.f, keycode) || match_keycode (Gdk.Key.F11, keycode)) {
133 if (player_page.fullscreened) {
134 unfullscreen ();
135 } else {
136@@ -309,6 +350,13 @@
137 player_page.seek_jump_seconds (600); // 10 mins
138 player_page.reveal_control ();
139 break;
140+ case Gdk.Key.minus:
141+ case Gdk.Key.plus:
142+ case Gdk.Key.equal:
143+ if (Gdk.ModifierType.CONTROL_MASK in e.state) {
144+ schedule_resize (e.keyval != Gdk.Key.minus);
145+ }
146+ break;
147 default:
148 break;
149 }
150@@ -342,6 +390,52 @@
151 return base.key_press_event (e);
152 }
153
154+ public bool on_scroll_event (Gdk.EventScroll e) {
155+ /* Ctrl-Scroll to resize only applies to player page */
156+ if (main_stack.get_visible_child () != player_page) {
157+ return false;
158+ }
159+
160+ switch (e.direction) {
161+ case Gdk.ScrollDirection.DOWN:
162+ case Gdk.ScrollDirection.UP:
163+ if (Gdk.ModifierType.CONTROL_MASK in e.state) {
164+ schedule_resize (e.direction == Gdk.ScrollDirection.UP);
165+ return true;
166+ }
167+ break;
168+ default:
169+ break;
170+ }
171+ return false;
172+ }
173+
174+ /* Limit the rate of window resizing by combining rapid events */
175+ private int total_horiz_increment = 0;
176+ private uint resize_timeout_id = 0;
177+ private void schedule_resize (bool increase) {
178+ if (resize_timeout_id == 0) {
179+ resize_timeout_id = Timeout.add (100, () => {
180+ Gtk.Allocation alloc = {};
181+ get_allocation (out alloc);
182+ int w = alloc.width + total_horiz_increment;
183+ int h = (int)((double)w * aspect_ratio) + added_height; // Ensure correct aspect maintained
184+
185+ resize (w, h);
186+
187+ resize_timeout_id = 0;
188+ total_horiz_increment = 0;
189+ return false;
190+ });
191+ }
192+
193+ if (increase) {
194+ total_horiz_increment += 10;
195+ } else {
196+ total_horiz_increment -= 10;
197+ }
198+ }
199+
200 public void open_files (File[] files, bool clear_playlist = false, bool force_play = true) {
201 if (clear_playlist) {
202 player_page.get_playlist_widget ().clear_items ();
203@@ -453,6 +547,10 @@
204 unfullscreen ();
205 }
206
207+ private void set_initial_size () {
208+ resize (DEFAULT_WIDTH, DEFAULT_HEIGHT);
209+ }
210+
211 public void play_file (string uri, bool from_beginning = true) {
212 search_entry.visible = false;
213 if (navigation_button.visible) {
214@@ -467,6 +565,10 @@
215 }
216
217 main_stack.set_visible_child_full ("player", Gtk.StackTransitionType.SLIDE_LEFT);
218+ if (last_video_allocation.width > 0) {
219+ resize (last_video_allocation.width, last_video_allocation.height);
220+ }
221+
222 player_page.play_file (uri, from_beginning);
223 if (is_maximized) {
224 fullscreen ();
225@@ -490,6 +592,14 @@
226 }
227 title = App.get_instance ().program_name;
228 get_window ().set_cursor (null);
229+ if (is_maximized) {
230+ unmaximize ();
231+ }
232+
233+ if (main_stack.get_visible_child () == player_page) {
234+ get_allocation (out last_video_allocation);
235+ }
236+ set_initial_size (); // return to default size for start page
237
238 if (navigation_button.label == _(navigation_button_library)) {
239 navigation_button.label = _(navigation_button_welcomescreen);

Subscribers

People subscribed via source and target branches