mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
Compare commits
594 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
147addbce1 | ||
|
|
104f8d6057 | ||
|
|
9c9ba80978 | ||
|
|
cbe9768529 | ||
|
|
ce847fc3ca | ||
|
|
3dd8377218 | ||
|
|
6fdf40b038 | ||
|
|
988e2334f5 | ||
|
|
741ae488d5 | ||
|
|
a13ed2a005 | ||
|
|
9367c764be | ||
|
|
4f57b685bd | ||
|
|
902a8c57bd | ||
|
|
21cfd330c0 | ||
|
|
c017a7a1c7 | ||
|
|
0756aa663b | ||
|
|
4ee94917a0 | ||
|
|
0df21afcdf | ||
|
|
433a825006 | ||
|
|
4f288e3ba2 | ||
|
|
392b59be4e | ||
|
|
6d8d211631 | ||
|
|
af17253a72 | ||
|
|
cfdea04c83 | ||
|
|
7584e73d70 | ||
|
|
eac5ba4c56 | ||
|
|
a9d5699a52 | ||
|
|
4e08264522 | ||
|
|
6b39e4a210 | ||
|
|
4a1c8f6cb7 | ||
|
|
468d5f6c7a | ||
|
|
a8382d6794 | ||
|
|
e899050500 | ||
|
|
b01fd9715b | ||
|
|
0417a3e51e | ||
|
|
0740b2f66b | ||
|
|
d686916fe2 | ||
|
|
fefc7c23f9 | ||
|
|
cef7525d00 | ||
|
|
b448b0c796 | ||
|
|
a97dc6d17a | ||
|
|
fcfc13c1ea | ||
|
|
1e4ef195bb | ||
|
|
566d76def2 | ||
|
|
f553d16539 | ||
|
|
8897a7a926 | ||
|
|
656ee0d9c3 | ||
|
|
ecc03fdd40 | ||
|
|
46cd8708a4 | ||
|
|
27e1938e9f | ||
|
|
17198c26d9 | ||
|
|
eaeebd3ebd | ||
|
|
253a383168 | ||
|
|
3e4a0705e9 | ||
|
|
7ef374477d | ||
|
|
4ae6103356 | ||
|
|
2e4322c230 | ||
|
|
6b7e375963 | ||
|
|
c46c1dbb1e | ||
|
|
af79f4793e | ||
|
|
774a15f4c8 | ||
|
|
b7c4cde11a | ||
|
|
9857aa25a3 | ||
|
|
d4a8a64ba7 | ||
|
|
af0098f064 | ||
|
|
37c53f2e09 | ||
|
|
a8e59ccd3d | ||
|
|
57852366bb | ||
|
|
a4832c304e | ||
|
|
156d823b7f | ||
|
|
45d9cc6405 | ||
|
|
0aeb53435e | ||
|
|
7dd1ebc734 | ||
|
|
ce694760bc | ||
|
|
c8189046fe | ||
|
|
2656812dea | ||
|
|
1978b39337 | ||
|
|
e7bfd1c959 | ||
|
|
663f8f4b54 | ||
|
|
9b0a32f62c | ||
|
|
06065d1c5d | ||
|
|
e84ae6e2aa | ||
|
|
13f9a6c273 | ||
|
|
d89b23c120 | ||
|
|
479451e7c7 | ||
|
|
ea8a4f2b51 | ||
|
|
e26189ba87 | ||
|
|
003522d6f7 | ||
|
|
4db6ccd579 | ||
|
|
39aa740c88 | ||
|
|
66f825beb1 | ||
|
|
75feeca0f0 | ||
|
|
120aa1c9ce | ||
|
|
7fa2ffc2a7 | ||
|
|
15fae91ac7 | ||
|
|
4ae190dab9 | ||
|
|
0baa60caab | ||
|
|
2a3bcdcaab | ||
|
|
619f74fa12 | ||
|
|
8aaf029e55 | ||
|
|
bcce7aff18 | ||
|
|
b575055d7e | ||
|
|
d5b3ef5380 | ||
|
|
58ef0bea17 | ||
|
|
7de6a06acf | ||
|
|
2cd10d339f | ||
|
|
38281f3364 | ||
|
|
25bcc2dd0d | ||
|
|
af27c62b07 | ||
|
|
8b16b82ce9 | ||
|
|
223e9d97a0 | ||
|
|
7b49d94e9f | ||
|
|
a677eb0f95 | ||
|
|
987579d391 | ||
|
|
99414065a9 | ||
|
|
e4b0577cb0 | ||
|
|
424afd3faf | ||
|
|
6fac14ad3f | ||
|
|
d69367aa9b | ||
|
|
2efb7a12cb | ||
|
|
9f616b934b | ||
|
|
c016e83eb3 | ||
|
|
7015dbf0d2 | ||
|
|
9f42c4c441 | ||
|
|
1841f826fe | ||
|
|
e24267d060 | ||
|
|
91591f37e6 | ||
|
|
8875296338 | ||
|
|
98eb8cd3c1 | ||
|
|
2acd7f4d12 | ||
|
|
4d49156dac | ||
|
|
c147e72c8e | ||
|
|
f872799f5c | ||
|
|
913bc8e198 | ||
|
|
c37740273f | ||
|
|
f09ed4b677 | ||
|
|
e52f5933a0 | ||
|
|
9339853448 | ||
|
|
12fb9f1f18 | ||
|
|
f3b182606b | ||
|
|
a0284a9bc5 | ||
|
|
09e5035ab5 | ||
|
|
b7e078e98d | ||
|
|
f80e81bf9f | ||
|
|
c34d868609 | ||
|
|
2b05c61ae3 | ||
|
|
b859afc118 | ||
|
|
03979936f3 | ||
|
|
4d7050553c | ||
|
|
c104858079 | ||
|
|
2c8781ed69 | ||
|
|
e38fc724f8 | ||
|
|
3bbfc4d420 | ||
|
|
217010a669 | ||
|
|
451cea4675 | ||
|
|
d39182b41a | ||
|
|
2cda2bd718 | ||
|
|
16e3991ffa | ||
|
|
fbbffe03a5 | ||
|
|
f61ace74bb | ||
|
|
4a8dcec63a | ||
|
|
30c6ca6751 | ||
|
|
84b7bb29f0 | ||
|
|
9d1d1f21e9 | ||
|
|
883c4b63d0 | ||
|
|
0380d3ae50 | ||
|
|
2fbb98a97c | ||
|
|
43702e0f8e | ||
|
|
56d9ce34e4 | ||
|
|
76abb2e18d | ||
|
|
a0db484510 | ||
|
|
b3b856f476 | ||
|
|
69a7025c96 | ||
|
|
773bfea386 | ||
|
|
eafc694bba | ||
|
|
81733a523e | ||
|
|
1afe501a36 | ||
|
|
f282b51c98 | ||
|
|
ac0658bbf1 | ||
|
|
116dbc0581 | ||
|
|
6af8a0fae4 | ||
|
|
79b5ae3d57 | ||
|
|
cb15181f43 | ||
|
|
9f342ebbd1 | ||
|
|
27795015ff | ||
|
|
79a5de3fd8 | ||
|
|
2624738534 | ||
|
|
10b91b1291 | ||
|
|
1781ceb25b | ||
|
|
051e5c27b3 | ||
|
|
5285b729be | ||
|
|
9bc6000cb5 | ||
|
|
fdf3f6ce30 | ||
|
|
0d930b65f1 | ||
|
|
16b3962b66 | ||
|
|
4b95f3a462 | ||
|
|
4ffae1d563 | ||
|
|
abffd98e29 | ||
|
|
56f9cc683a | ||
|
|
49cc00dedf | ||
|
|
9fa13710aa | ||
|
|
0eda33f057 | ||
|
|
2b4fff70d5 | ||
|
|
a80f4c1605 | ||
|
|
6aba4e916a | ||
|
|
6a7f0d70fd | ||
|
|
042684fb38 | ||
|
|
018575de71 | ||
|
|
8c0588d4e0 | ||
|
|
aaa8c56686 | ||
|
|
5e936a24ac | ||
|
|
edd80d88a9 | ||
|
|
25659e482e | ||
|
|
a097d17166 | ||
|
|
d4bbc24031 | ||
|
|
3dd41bc09a | ||
|
|
9490ec7686 | ||
|
|
a2b3cf95a7 | ||
|
|
cc7f4fedf6 | ||
|
|
22bd7c0271 | ||
|
|
3408c8038e | ||
|
|
5a4cdcfde1 | ||
|
|
0babe4a5ed | ||
|
|
a538b37854 | ||
|
|
ebaeec1677 | ||
|
|
1f1d9cefca | ||
|
|
a846088eac | ||
|
|
43f4eb76c4 | ||
|
|
29b9fbcc9a | ||
|
|
4d10b9a31b | ||
|
|
0727102c5e | ||
|
|
4c2590ed92 | ||
|
|
66ce176b22 | ||
|
|
a824ff479a | ||
|
|
c88c6b1323 | ||
|
|
b459f00bd3 | ||
|
|
00376c1d59 | ||
|
|
85a8b149bb | ||
|
|
3fcb57559a | ||
|
|
bf21892cfa | ||
|
|
c4576463e2 | ||
|
|
3af686daff | ||
|
|
c811188e22 | ||
|
|
ef88a06f08 | ||
|
|
cf050ff9e2 | ||
|
|
bb04069e83 | ||
|
|
a938859eb8 | ||
|
|
8d35576a36 | ||
|
|
9cae04edde | ||
|
|
11684c2c73 | ||
|
|
e258973490 | ||
|
|
00d57fa547 | ||
|
|
24106469c5 | ||
|
|
9c55280917 | ||
|
|
98333049ec | ||
|
|
63b45a873b | ||
|
|
ec34bfde26 | ||
|
|
8ae91ea2ee | ||
|
|
772c456513 | ||
|
|
3a4cd19226 | ||
|
|
4d8c1c61a5 | ||
|
|
bee3abe334 | ||
|
|
5d1c626a53 | ||
|
|
fb612075c4 | ||
|
|
7c5d3296e7 | ||
|
|
002b9b5d4b | ||
|
|
a0a23e04cf | ||
|
|
763fdb4be1 | ||
|
|
4d0cef5070 | ||
|
|
18c7ba94f8 | ||
|
|
5fb72b5e05 | ||
|
|
960971b195 | ||
|
|
b10a6422d4 | ||
|
|
2714f280f5 | ||
|
|
9c53d241fa | ||
|
|
f4d33e366d | ||
|
|
73cdf35c98 | ||
|
|
140651c258 | ||
|
|
ff6a8fac2a | ||
|
|
1807458c66 | ||
|
|
fb41474555 | ||
|
|
3f390c6849 | ||
|
|
4a186069d9 | ||
|
|
d942694695 | ||
|
|
766f5afabd | ||
|
|
e16fa08e61 | ||
|
|
b07d4eba11 | ||
|
|
f1d1070baa | ||
|
|
0c146de7dd | ||
|
|
5a56de501a | ||
|
|
11d16a7342 | ||
|
|
1b5db42ec6 | ||
|
|
0b6b4ca50d | ||
|
|
e7e8b3fdb6 | ||
|
|
5bfa898a02 | ||
|
|
770a3509cf | ||
|
|
b14870d9a1 | ||
|
|
52340b43f5 | ||
|
|
1323542373 | ||
|
|
24b9313958 | ||
|
|
0e1290fc10 | ||
|
|
8abe8fe01d | ||
|
|
77b35ba7ab | ||
|
|
96e48ac13c | ||
|
|
d83534d513 | ||
|
|
19c7ee0932 | ||
|
|
24bcf6ac16 | ||
|
|
5d23d165a9 | ||
|
|
b3b9994ce8 | ||
|
|
df0bda058f | ||
|
|
15b8449411 | ||
|
|
e1d68fa3cd | ||
|
|
2c9ce3f3e0 | ||
|
|
734f42b5f9 | ||
|
|
3cff64001d | ||
|
|
241297fb2e | ||
|
|
d4583006b3 | ||
|
|
d42e51e33a | ||
|
|
3bed19d70d | ||
|
|
fd6ef6712f | ||
|
|
c51982a231 | ||
|
|
53d4c36332 | ||
|
|
de76bf5f63 | ||
|
|
e0e47ea9a1 | ||
|
|
3989139378 | ||
|
|
ca68dfe097 | ||
|
|
5114d571df | ||
|
|
08808664b6 | ||
|
|
13de65d310 | ||
|
|
6728efe87e | ||
|
|
458c4dd129 | ||
|
|
ef45b67dbf | ||
|
|
604700187d | ||
|
|
7e1ae369ed | ||
|
|
9850af93c9 | ||
|
|
4c8d0ab804 | ||
|
|
47fd41715f | ||
|
|
a64978b812 | ||
|
|
524bab530a | ||
|
|
72154b64ed | ||
|
|
695509e267 | ||
|
|
0f7652dc85 | ||
|
|
1713200084 | ||
|
|
6afe8aa7f2 | ||
|
|
c8629019f5 | ||
|
|
a7b6332ed0 | ||
|
|
06cc9a44fe | ||
|
|
0b3b29938f | ||
|
|
1b1541fe1a | ||
|
|
1d228446db | ||
|
|
c783ec72bc | ||
|
|
90c5972fce | ||
|
|
1f677ed361 | ||
|
|
9c19b4e3d5 | ||
|
|
d4a1f396fb | ||
|
|
72e3816143 | ||
|
|
9dd181c206 | ||
|
|
9828926002 | ||
|
|
bb955b6202 | ||
|
|
1dd05ff520 | ||
|
|
19bd5ea8ba | ||
|
|
bcf7a86dc7 | ||
|
|
2fbdac1034 | ||
|
|
577585df63 | ||
|
|
f13bd655a1 | ||
|
|
81de0518d9 | ||
|
|
d93a86e8cc | ||
|
|
7e186cee55 | ||
|
|
97da066ae2 | ||
|
|
b58f73b5c9 | ||
|
|
ad1cb16a76 | ||
|
|
cd4a66dca5 | ||
|
|
cc282a1114 | ||
|
|
270d6f774a | ||
|
|
987a2e173a | ||
|
|
66efaa5e0f | ||
|
|
27a9f960de | ||
|
|
74e03d285e | ||
|
|
123f2a8265 | ||
|
|
d25c2d0f41 | ||
|
|
d2a701a465 | ||
|
|
1df30821db | ||
|
|
bf88fe32fd | ||
|
|
e21d5bd380 | ||
|
|
04bdc87283 | ||
|
|
177ccbc014 | ||
|
|
d6cd9e3034 | ||
|
|
d391f1b527 | ||
|
|
8c7a4de27b | ||
|
|
7cd7894878 | ||
|
|
d7fc7ef2ee | ||
|
|
6aef061362 | ||
|
|
e4943b3ab3 | ||
|
|
091136908d | ||
|
|
c6390e71d9 | ||
|
|
ab5e51c209 | ||
|
|
938b9e897a | ||
|
|
924033c2ba | ||
|
|
99e256f461 | ||
|
|
d2bcbafe73 | ||
|
|
5c07643d24 | ||
|
|
56d62ff589 | ||
|
|
62375663ab | ||
|
|
f5694daeb7 | ||
|
|
3a73625ece | ||
|
|
3b45f5a8e9 | ||
|
|
78791763cf | ||
|
|
81b55c1700 | ||
|
|
39a3ffdb9d | ||
|
|
df03c92249 | ||
|
|
c336cf59c1 | ||
|
|
fcd6fd9fd5 | ||
|
|
1ec173ad81 | ||
|
|
bce62622bb | ||
|
|
1290ddb5c9 | ||
|
|
ea42722918 | ||
|
|
aac09e5234 | ||
|
|
df3896b143 | ||
|
|
903bf444d9 | ||
|
|
3dad8734a0 | ||
|
|
762a5bbefa | ||
|
|
d3a175cea8 | ||
|
|
4e0f810148 | ||
|
|
32543997d4 | ||
|
|
c9a3ab3a81 | ||
|
|
3b4a071723 | ||
|
|
de9b01409b | ||
|
|
296a53536d | ||
|
|
783d47f78b | ||
|
|
b35bde662a | ||
|
|
ad783652c8 | ||
|
|
7ba947aee9 | ||
|
|
696e5e73bc | ||
|
|
a723d17f49 | ||
|
|
f8236c1a65 | ||
|
|
546c0e7822 | ||
|
|
e7c4d2523b | ||
|
|
fbb3a288ec | ||
|
|
cae15ad6b5 | ||
|
|
ed465208a2 | ||
|
|
c2c48c4079 | ||
|
|
dc7d2dab68 | ||
|
|
146970d29d | ||
|
|
ba2cb42f0d | ||
|
|
7dfe1a59b1 | ||
|
|
4343f762ac | ||
|
|
e2f53c6bcc | ||
|
|
5c22f2ca5d | ||
|
|
b6d4014bd5 | ||
|
|
6b8f5f5b7f | ||
|
|
b7e2f819a3 | ||
|
|
a8e0e8d7fd | ||
|
|
beea9a7c36 | ||
|
|
a44d7a3bc6 | ||
|
|
b45db70d21 | ||
|
|
8feff471ce | ||
|
|
00dec166e9 | ||
|
|
ebbbaf1ab0 | ||
|
|
29312186de | ||
|
|
e1d9e4ffcb | ||
|
|
b6c04c9e35 | ||
|
|
405b411a29 | ||
|
|
582fc50cf6 | ||
|
|
b74cfda7b9 | ||
|
|
805ce0dee9 | ||
|
|
f4a8fb9eb4 | ||
|
|
85702604c3 | ||
|
|
98999f4850 | ||
|
|
b5e1571204 | ||
|
|
d7934e7525 | ||
|
|
7fcba6ba0f | ||
|
|
ea1927f428 | ||
|
|
fa2aaa48b1 | ||
|
|
dee383db07 | ||
|
|
04a1dc8e1e | ||
|
|
ae31ded165 | ||
|
|
402e977b40 | ||
|
|
a65c8cae63 | ||
|
|
47a03d3ca1 | ||
|
|
b4a13fda3a | ||
|
|
e11672d42b | ||
|
|
30a6b597a5 | ||
|
|
c45ca254e3 | ||
|
|
143d7ab98f | ||
|
|
e3e450613d | ||
|
|
77fdc67235 | ||
|
|
61e50046bd | ||
|
|
1cdf8bbc10 | ||
|
|
a3d2cdaa2c | ||
|
|
159e2f2dab | ||
|
|
e8f3cf164b | ||
|
|
456f102cdc | ||
|
|
ba98109d33 | ||
|
|
9f94652792 | ||
|
|
1454510549 | ||
|
|
c0f8b4895d | ||
|
|
5dd5dbb3d8 | ||
|
|
48fd2bd35f | ||
|
|
29fa48d8c3 | ||
|
|
90bff4d9de | ||
|
|
b05254807b | ||
|
|
e504d82554 | ||
|
|
5bf746700e | ||
|
|
07a08077a2 | ||
|
|
26004f1a66 | ||
|
|
1c6586c4b9 | ||
|
|
0ac4b89a0a | ||
|
|
6de1eef078 | ||
|
|
1fd819e500 | ||
|
|
a260647b4f | ||
|
|
ffe931bde7 | ||
|
|
27bc6c7883 | ||
|
|
6c340cece8 | ||
|
|
64718173ef | ||
|
|
43f955194e | ||
|
|
8567f79e67 | ||
|
|
269a87b26f | ||
|
|
084110c56f | ||
|
|
47df447e4f | ||
|
|
1072519488 | ||
|
|
37de2301f7 | ||
|
|
fec5a7d67a | ||
|
|
8baaad4e0d | ||
|
|
10ea0268e5 | ||
|
|
b4c220613f | ||
|
|
d4b204799d | ||
|
|
12a2b144f3 | ||
|
|
7df86c48fa | ||
|
|
0c3ad527e3 | ||
|
|
37e30cef60 | ||
|
|
0fda86f79a | ||
|
|
e77d7e7f62 | ||
|
|
5d0f3534eb | ||
|
|
577394442b | ||
|
|
d1274bb79f | ||
|
|
da677b683b | ||
|
|
9dad9478fa | ||
|
|
ea244a5188 | ||
|
|
69d4cac760 | ||
|
|
e7f1265b64 | ||
|
|
94faaf7d58 | ||
|
|
d426d4ad90 | ||
|
|
64e53a17bd | ||
|
|
20d5a50ac9 | ||
|
|
9714348260 | ||
|
|
787bc85703 | ||
|
|
e62e62292a | ||
|
|
b84d29fb32 | ||
|
|
5be8104104 | ||
|
|
eef42770c6 | ||
|
|
f792c720f4 | ||
|
|
359ab2f9b3 | ||
|
|
bc13536208 | ||
|
|
0d4872755c | ||
|
|
4627311c34 | ||
|
|
dc2ced14b8 | ||
|
|
eafb6307d5 | ||
|
|
fbac635687 | ||
|
|
5ccd0a24e9 | ||
|
|
f8bdc7437d | ||
|
|
1de2b77ee4 | ||
|
|
18fd3e0329 | ||
|
|
a510642a25 | ||
|
|
30dd65e3a9 | ||
|
|
5708e86a05 | ||
|
|
937ae7ef8f | ||
|
|
4c56c1c2b2 | ||
|
|
6d8f900916 | ||
|
|
4aa292c7cd | ||
|
|
f28e8d7168 | ||
|
|
2e0a1a8a64 | ||
|
|
56b40ae6d2 | ||
|
|
9e8b0953f3 | ||
|
|
893fc2cd53 | ||
|
|
2435f1b660 | ||
|
|
afb551e94a | ||
|
|
5754f3aea0 | ||
|
|
d3dc66e308 | ||
|
|
313b2faa3c | ||
|
|
18585204b7 | ||
|
|
3d40c720dd | ||
|
|
8d201ae1ad | ||
|
|
67c89b68d3 | ||
|
|
5937d37fc5 | ||
|
|
56a644d49f | ||
|
|
0c54700b16 | ||
|
|
3a5bf51d1d | ||
|
|
7b85ca0301 | ||
|
|
5cbc8d5c71 | ||
|
|
be4bc6b7ef | ||
|
|
d2e40d4fc1 | ||
|
|
a23e7ecf8f | ||
|
|
0fb2339e3d | ||
|
|
2b0f632d51 |
35
.clang-format
Normal file
35
.clang-format
Normal file
@@ -0,0 +1,35 @@
|
||||
# Defines the Chromium style for automatic reformatting.
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
BasedOnStyle: Chromium
|
||||
# This defaults to 'Auto'. Explicitly set it for a while, so that
|
||||
# 'vector<vector<int> >' in existing files gets formatted to
|
||||
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
|
||||
# 'int>>' if the file already contains at least one such instance.)
|
||||
Standard: Cpp11
|
||||
# Make sure code like:
|
||||
# IPC_BEGIN_MESSAGE_MAP()
|
||||
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
|
||||
# IPC_END_MESSAGE_MAP()
|
||||
# gets correctly indented.
|
||||
MacroBlockBegin: "^\
|
||||
BEGIN_MSG_MAP|\
|
||||
BEGIN_MSG_MAP_EX|\
|
||||
BEGIN_SAFE_MSG_MAP_EX|\
|
||||
CR_BEGIN_MSG_MAP_EX|\
|
||||
IPC_BEGIN_MESSAGE_MAP|\
|
||||
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
|
||||
IPC_STRUCT_BEGIN|\
|
||||
IPC_STRUCT_BEGIN_WITH_PARENT|\
|
||||
IPC_STRUCT_TRAITS_BEGIN|\
|
||||
POLPARAMS_BEGIN|\
|
||||
PPAPI_BEGIN_MESSAGE_MAP$"
|
||||
MacroBlockEnd: "^\
|
||||
CR_END_MSG_MAP|\
|
||||
END_MSG_MAP|\
|
||||
IPC_END_MESSAGE_MAP|\
|
||||
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
|
||||
IPC_STRUCT_END|\
|
||||
IPC_STRUCT_TRAITS_END|\
|
||||
POLPARAMS_END|\
|
||||
PPAPI_END_MESSAGE_MAP$"
|
||||
@@ -1,6 +1,6 @@
|
||||
# Contributing to Electron
|
||||
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md)
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/CONTRIBUTING.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/CONTRIBUTING.md) | [Brazilian Portuguese](https://github.com/electron/electron/tree/master/docs-translations/pt-BR/project/CONTRIBUTING.md) | [Dutch](https://github.com/electron/electron/tree/master/docs-translations/nl/project/CONTRIBUTING.md)
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2014 GitHub Inc.
|
||||
Copyright (c) 2016 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[](https://travis-ci.org/electron/electron)
|
||||
[](https://ci.appveyor.com/project/Atom/electron)
|
||||
[](https://david-dm.org/electron/electron#info=devDependencies)
|
||||
[](https://david-dm.org/electron/electron?type=dev)
|
||||
[](http://atom-slack.herokuapp.com/)
|
||||
|
||||
:memo: Available Translations: [Korean](https://github.com/electron/electron/tree/master/docs-translations/ko-KR/project/README.md) | [Simplified Chinese](https://github.com/electron/electron/tree/master/docs-translations/zh-CN/project/README.md)
|
||||
@@ -79,3 +79,7 @@ forums
|
||||
|
||||
Check out [awesome-electron](https://github.com/sindresorhus/awesome-electron)
|
||||
for a community maintained list of useful example apps, tools and resources.
|
||||
|
||||
## License
|
||||
|
||||
MIT © 2016 Github
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/browser/relauncher.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "atom/renderer/atom_renderer_client.h"
|
||||
#include "atom/renderer/atom_sandboxed_renderer_client.h"
|
||||
#include "atom/utility/atom_content_utility_client.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/debug/stack_trace.h"
|
||||
@@ -29,7 +31,7 @@ namespace {
|
||||
const char* kRelauncherProcess = "relauncher";
|
||||
|
||||
bool IsBrowserProcess(base::CommandLine* cmd) {
|
||||
std::string process_type = cmd->GetSwitchValueASCII(switches::kProcessType);
|
||||
std::string process_type = cmd->GetSwitchValueASCII(::switches::kProcessType);
|
||||
return process_type.empty();
|
||||
}
|
||||
|
||||
@@ -72,7 +74,7 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) {
|
||||
|
||||
// Only enable logging when --enable-logging is specified.
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
if (!command_line->HasSwitch(switches::kEnableLogging) &&
|
||||
if (!command_line->HasSwitch(::switches::kEnableLogging) &&
|
||||
!env->HasVar("ELECTRON_ENABLE_LOGGING")) {
|
||||
settings.logging_dest = logging::LOG_NONE;
|
||||
logging::SetMinLogLevel(logging::LOG_NUM_SEVERITIES);
|
||||
@@ -115,17 +117,23 @@ void AtomMainDelegate::PreSandboxStartup() {
|
||||
|
||||
auto command_line = base::CommandLine::ForCurrentProcess();
|
||||
std::string process_type = command_line->GetSwitchValueASCII(
|
||||
switches::kProcessType);
|
||||
::switches::kProcessType);
|
||||
|
||||
// Only append arguments for browser process.
|
||||
if (!IsBrowserProcess(command_line))
|
||||
return;
|
||||
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(switches::kNoSandbox);
|
||||
if (command_line->HasSwitch(switches::kEnableSandbox)) {
|
||||
// Disable setuid sandbox since it is not longer required on linux(namespace
|
||||
// sandbox is available on most distros).
|
||||
command_line->AppendSwitch(::switches::kDisableSetuidSandbox);
|
||||
} else {
|
||||
// Disable renderer sandbox for most of node's functions.
|
||||
command_line->AppendSwitch(::switches::kNoSandbox);
|
||||
}
|
||||
|
||||
// Allow file:// URIs to read other file:// URIs by default.
|
||||
command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
|
||||
command_line->AppendSwitch(::switches::kAllowFileAccessFromFiles);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// Enable AVFoundation.
|
||||
@@ -140,7 +148,13 @@ content::ContentBrowserClient* AtomMainDelegate::CreateContentBrowserClient() {
|
||||
|
||||
content::ContentRendererClient*
|
||||
AtomMainDelegate::CreateContentRendererClient() {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kEnableSandbox)) {
|
||||
renderer_client_.reset(new AtomSandboxedRendererClient);
|
||||
} else {
|
||||
renderer_client_.reset(new AtomRendererClient);
|
||||
}
|
||||
|
||||
return renderer_client_.get();
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "gin/v8_initializer.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/common/api/atom_bindings.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -51,6 +57,11 @@ int NodeMain(int argc, char *argv[]) {
|
||||
if (node_debugger.IsRunning())
|
||||
env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
#if defined(OS_WIN)
|
||||
mate::Dictionary process(gin_env.isolate(), env->process_object());
|
||||
process.SetMethod("log", &AtomBindings::Log);
|
||||
#endif
|
||||
|
||||
node::LoadEnvironment(env);
|
||||
|
||||
bool more;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "media/audio/audio_manager.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
@@ -490,6 +491,11 @@ void App::OnWillFinishLaunching() {
|
||||
}
|
||||
|
||||
void App::OnFinishLaunching(const base::DictionaryValue& launch_info) {
|
||||
#if defined(OS_LINUX)
|
||||
// Set the application name for audio streams shown in external
|
||||
// applications. Only affects pulseaudio currently.
|
||||
media::AudioManager::SetGlobalAppName(Browser::Get()->GetName());
|
||||
#endif
|
||||
Emit("ready", launch_info);
|
||||
}
|
||||
|
||||
@@ -525,6 +531,7 @@ void App::OnLogin(LoginHandler* login_handler,
|
||||
void App::OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const std::vector<base::string16>& features,
|
||||
int render_process_id,
|
||||
int render_frame_id) {
|
||||
v8::Locker locker(isolate());
|
||||
@@ -535,7 +542,10 @@ void App::OnCreateWindow(const GURL& target_url,
|
||||
content::WebContents::FromRenderFrameHost(rfh);
|
||||
if (web_contents) {
|
||||
auto api_web_contents = WebContents::CreateFrom(isolate(), web_contents);
|
||||
api_web_contents->OnCreateWindow(target_url, frame_name, disposition);
|
||||
api_web_contents->OnCreateWindow(target_url,
|
||||
frame_name,
|
||||
disposition,
|
||||
features);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,8 +595,9 @@ void App::SelectClientCertificate(
|
||||
cert_request_info->client_certs[0].get());
|
||||
}
|
||||
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus exit_code) {
|
||||
Emit("gpu-process-crashed");
|
||||
void App::OnGpuProcessCrashed(base::TerminationStatus status) {
|
||||
Emit("gpu-process-crashed",
|
||||
status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||
}
|
||||
|
||||
base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
@@ -596,7 +607,7 @@ base::FilePath App::GetPath(mate::Arguments* args, const std::string& name) {
|
||||
if (key >= 0)
|
||||
succeed = PathService::Get(key, &path);
|
||||
if (!succeed)
|
||||
args->ThrowError("Failed to get path");
|
||||
args->ThrowError("Failed to get '" + name + "' path");
|
||||
return path;
|
||||
}
|
||||
|
||||
@@ -604,7 +615,7 @@ void App::SetPath(mate::Arguments* args,
|
||||
const std::string& name,
|
||||
const base::FilePath& path) {
|
||||
if (!path.IsAbsolute()) {
|
||||
args->ThrowError("path must be absolute");
|
||||
args->ThrowError("Path must be absolute");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -839,6 +850,8 @@ void App::BuildPrototype(
|
||||
base::Bind(&Browser::SetUserActivity, browser))
|
||||
.SetMethod("getCurrentActivityType",
|
||||
base::Bind(&Browser::GetCurrentActivityType, browser))
|
||||
.SetMethod("setAboutPanelOptions",
|
||||
base::Bind(&Browser::SetAboutPanelOptions, browser))
|
||||
#endif
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("setUserTasks", base::Bind(&Browser::SetUserTasks, browser))
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ATOM_BROWSER_API_ATOM_API_APP_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/api/event_emitter.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
@@ -50,6 +51,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition,
|
||||
const std::vector<base::string16>& features,
|
||||
int render_process_id,
|
||||
int render_frame_id);
|
||||
|
||||
@@ -102,7 +104,7 @@ class App : public AtomBrowserClient::Delegate,
|
||||
std::unique_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
|
||||
// content::GpuDataManagerObserver:
|
||||
void OnGpuProcessCrashed(base::TerminationStatus exit_code) override;
|
||||
void OnGpuProcessCrashed(base::TerminationStatus status) override;
|
||||
|
||||
private:
|
||||
// Get/Set the pre-defined path in PathService.
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "content/public/browser/tracing_controller.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::TracingController;
|
||||
|
||||
namespace mate {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "net/url_request/url_request_context.h"
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
|
||||
using atom::AtomCookieDelegate;
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace mate {
|
||||
@@ -54,6 +55,27 @@ struct Converter<net::CanonicalCookie> {
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Converter<AtomCookieDelegate::ChangeCause> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const AtomCookieDelegate::ChangeCause& val) {
|
||||
switch (val) {
|
||||
case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPLICIT:
|
||||
return mate::StringToV8(isolate, "explicit");
|
||||
case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_OVERWRITE:
|
||||
return mate::StringToV8(isolate, "overwrite");
|
||||
case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPIRED:
|
||||
return mate::StringToV8(isolate, "expired");
|
||||
case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EVICTED:
|
||||
return mate::StringToV8(isolate, "evicted");
|
||||
case AtomCookieDelegate::ChangeCause::CHANGE_COOKIE_EXPIRED_OVERWRITE:
|
||||
return mate::StringToV8(isolate, "expired-overwrite");
|
||||
default:
|
||||
return mate::StringToV8(isolate, "unknown");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
||||
namespace atom {
|
||||
@@ -206,11 +228,14 @@ void SetCookieOnIO(scoped_refptr<net::URLRequestContextGetter> getter,
|
||||
|
||||
Cookies::Cookies(v8::Isolate* isolate,
|
||||
AtomBrowserContext* browser_context)
|
||||
: request_context_getter_(browser_context->url_request_context_getter()) {
|
||||
: request_context_getter_(browser_context->url_request_context_getter()),
|
||||
cookie_delegate_(browser_context->cookie_delegate()) {
|
||||
Init(isolate);
|
||||
cookie_delegate_->AddObserver(this);
|
||||
}
|
||||
|
||||
Cookies::~Cookies() {
|
||||
cookie_delegate_->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void Cookies::Get(const base::DictionaryValue& filter,
|
||||
@@ -239,6 +264,13 @@ void Cookies::Set(const base::DictionaryValue& details,
|
||||
base::Bind(SetCookieOnIO, getter, Passed(&copied), callback));
|
||||
}
|
||||
|
||||
void Cookies::OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
AtomCookieDelegate::ChangeCause cause) {
|
||||
Emit("changed", cookie, cause, removed);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
mate::Handle<Cookies> Cookies::Create(
|
||||
v8::Isolate* isolate,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/net/atom_cookie_delegate.h"
|
||||
#include "base/callback.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "net/cookies/canonical_cookie.h"
|
||||
@@ -26,7 +27,8 @@ class AtomBrowserContext;
|
||||
|
||||
namespace api {
|
||||
|
||||
class Cookies : public mate::TrackableObject<Cookies> {
|
||||
class Cookies : public mate::TrackableObject<Cookies>,
|
||||
public AtomCookieDelegate::Observer {
|
||||
public:
|
||||
enum Error {
|
||||
SUCCESS,
|
||||
@@ -52,8 +54,14 @@ class Cookies : public mate::TrackableObject<Cookies> {
|
||||
const base::Closure& callback);
|
||||
void Set(const base::DictionaryValue& details, const SetCallback& callback);
|
||||
|
||||
// AtomCookieDelegate::Observer:
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
AtomCookieDelegate::ChangeCause cause) override;
|
||||
|
||||
private:
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Cookies);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
#include "content/public/browser/devtools_agent_host.h"
|
||||
@@ -17,6 +16,8 @@
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::DevToolsAgentHost;
|
||||
|
||||
namespace atom {
|
||||
@@ -107,7 +108,7 @@ bool Debugger::IsAttached() {
|
||||
void Debugger::Detach() {
|
||||
if (!agent_host_.get())
|
||||
return;
|
||||
agent_host_->DetachClient();
|
||||
agent_host_->DetachClient(this);
|
||||
AgentHostClosed(agent_host_.get(), false);
|
||||
agent_host_ = nullptr;
|
||||
}
|
||||
@@ -136,7 +137,7 @@ void Debugger::SendCommand(mate::Arguments* args) {
|
||||
|
||||
std::string json_args;
|
||||
base::JSONWriter::Write(request, &json_args);
|
||||
agent_host_->DispatchProtocolMessage(json_args);
|
||||
agent_host_->DispatchProtocolMessage(this, json_args);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
#include "atom/common/native_mate_converters/callback.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "net/base/filename_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
@@ -134,7 +135,7 @@ std::string DownloadItem::GetFilename() const {
|
||||
std::string(),
|
||||
download_item_->GetSuggestedFilename(),
|
||||
GetMimeType(),
|
||||
std::string()).LossyDisplayName());
|
||||
"download").LossyDisplayName());
|
||||
}
|
||||
|
||||
std::string DownloadItem::GetContentDisposition() const {
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
#include "atom/browser/api/atom_api_power_monitor.h"
|
||||
|
||||
#include "atom/browser/browser.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/power_monitor/power_monitor.h"
|
||||
#include "base/power_monitor/power_monitor_device_source.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -43,7 +44,7 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot initialize \"power-monitor\" module before app is ready")));
|
||||
"Cannot require \"powerMonitor\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,18 +6,19 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
template<>
|
||||
struct Converter<content::PowerSaveBlocker::PowerSaveBlockerType> {
|
||||
struct Converter<device::PowerSaveBlocker::PowerSaveBlockerType> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
||||
using content::PowerSaveBlocker;
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType* out) {
|
||||
using device::PowerSaveBlocker;
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
@@ -39,7 +40,7 @@ namespace api {
|
||||
|
||||
PowerSaveBlocker::PowerSaveBlocker(v8::Isolate* isolate)
|
||||
: current_blocker_type_(
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension) {
|
||||
Init(isolate);
|
||||
}
|
||||
|
||||
@@ -58,30 +59,34 @@ void PowerSaveBlocker::UpdatePowerSaveBlocker() {
|
||||
// higher precedence level than |kPowerSaveBlockPreventAppSuspension|.
|
||||
//
|
||||
// Only the highest-precedence blocker type takes effect.
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType new_blocker_type =
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension;
|
||||
for (const auto& element : power_save_blocker_types_) {
|
||||
if (element.second ==
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep) {
|
||||
new_blocker_type =
|
||||
content::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
device::PowerSaveBlocker::kPowerSaveBlockPreventDisplaySleep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!power_save_blocker_ || new_blocker_type != current_blocker_type_) {
|
||||
std::unique_ptr<content::PowerSaveBlocker> new_blocker =
|
||||
content::PowerSaveBlocker::Create(
|
||||
std::unique_ptr<device::PowerSaveBlocker> new_blocker(
|
||||
new device::PowerSaveBlocker(
|
||||
new_blocker_type,
|
||||
content::PowerSaveBlocker::kReasonOther,
|
||||
ATOM_PRODUCT_NAME);
|
||||
device::PowerSaveBlocker::kReasonOther,
|
||||
ATOM_PRODUCT_NAME,
|
||||
content::BrowserThread::GetMessageLoopProxyForThread(
|
||||
content::BrowserThread::UI),
|
||||
content::BrowserThread::GetMessageLoopProxyForThread(
|
||||
content::BrowserThread::FILE)));
|
||||
power_save_blocker_.swap(new_blocker);
|
||||
current_blocker_type_ = new_blocker_type;
|
||||
}
|
||||
}
|
||||
|
||||
int PowerSaveBlocker::Start(
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType type) {
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType type) {
|
||||
static int count = 0;
|
||||
power_save_blocker_types_[count] = type;
|
||||
UpdatePowerSaveBlocker();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "content/public/browser/power_save_blocker.h"
|
||||
#include "device/power_save_blocker/power_save_blocker.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
namespace mate {
|
||||
@@ -33,18 +33,18 @@ class PowerSaveBlocker : public mate::TrackableObject<PowerSaveBlocker> {
|
||||
|
||||
private:
|
||||
void UpdatePowerSaveBlocker();
|
||||
int Start(content::PowerSaveBlocker::PowerSaveBlockerType type);
|
||||
int Start(device::PowerSaveBlocker::PowerSaveBlockerType type);
|
||||
bool Stop(int id);
|
||||
bool IsStarted(int id);
|
||||
|
||||
std::unique_ptr<content::PowerSaveBlocker> power_save_blocker_;
|
||||
std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
|
||||
|
||||
// Currnet blocker type used by |power_save_blocker_|
|
||||
content::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
||||
device::PowerSaveBlocker::PowerSaveBlockerType current_blocker_type_;
|
||||
|
||||
// Map from id to the corresponding blocker type for each request.
|
||||
using PowerSaveBlockerTypeMap =
|
||||
std::map<int, content::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
std::map<int, device::PowerSaveBlocker::PowerSaveBlockerType>;
|
||||
PowerSaveBlockerTypeMap power_save_blocker_types_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PowerSaveBlocker);
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
#include "atom/browser/atom_browser_client.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
@@ -97,7 +97,7 @@ v8::Local<v8::Value> Screen::Create(v8::Isolate* isolate) {
|
||||
if (!Browser::Get()->is_ready()) {
|
||||
isolate->ThrowException(v8::Exception::Error(mate::StringToV8(
|
||||
isolate,
|
||||
"Cannot initialize \"screen\" module before app is ready")));
|
||||
"Cannot require \"screen\" module before app is ready")));
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "net/url_request/url_request_context_getter.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
|
||||
using atom::api::Cookies;
|
||||
using content::BrowserThread;
|
||||
using content::StoragePartition;
|
||||
|
||||
@@ -335,7 +336,7 @@ void OnClearStorageDataDone(const base::Closure& callback) {
|
||||
Session::Session(v8::Isolate* isolate, AtomBrowserContext* browser_context)
|
||||
: devtools_network_emulation_client_id_(base::GenerateGUID()),
|
||||
browser_context_(browser_context) {
|
||||
// Observe DownloadManger to get download notifications.
|
||||
// Observe DownloadManager to get download notifications.
|
||||
content::BrowserContext::GetDownloadManager(browser_context)->
|
||||
AddObserver(this);
|
||||
|
||||
@@ -504,9 +505,24 @@ std::string Session::GetUserAgent() {
|
||||
return browser_context_->GetUserAgent();
|
||||
}
|
||||
|
||||
void Session::GetBlobData(
|
||||
const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback) {
|
||||
if (callback.is_null())
|
||||
return;
|
||||
|
||||
AtomBlobReader* blob_reader =
|
||||
browser_context()->GetBlobReader();
|
||||
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
|
||||
base::Bind(&AtomBlobReader::StartReading,
|
||||
base::Unretained(blob_reader),
|
||||
uuid,
|
||||
callback));
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Session::Cookies(v8::Isolate* isolate) {
|
||||
if (cookies_.IsEmpty()) {
|
||||
auto handle = atom::api::Cookies::Create(isolate, browser_context());
|
||||
auto handle = Cookies::Create(isolate, browser_context());
|
||||
cookies_.Reset(isolate, handle.ToV8());
|
||||
}
|
||||
return v8::Local<v8::Value>::New(isolate, cookies_);
|
||||
@@ -586,6 +602,7 @@ void Session::BuildPrototype(v8::Isolate* isolate,
|
||||
&Session::AllowNTLMCredentialsForDomains)
|
||||
.SetMethod("setUserAgent", &Session::SetUserAgent)
|
||||
.SetMethod("getUserAgent", &Session::GetUserAgent)
|
||||
.SetMethod("getBlobData", &Session::GetBlobData)
|
||||
.SetProperty("cookies", &Session::Cookies)
|
||||
.SetProperty("protocol", &Session::Protocol)
|
||||
.SetProperty("webRequest", &Session::WebRequest);
|
||||
@@ -615,6 +632,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
mate::Dictionary dict(isolate, exports);
|
||||
dict.Set("Session", Session::GetConstructor(isolate)->GetFunction());
|
||||
dict.Set("Cookies", Cookies::GetConstructor(isolate)->GetFunction());
|
||||
dict.SetMethod("fromPartition", &FromPartition);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/browser/api/trackable_object.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "base/values.h"
|
||||
#include "content/public/browser/download_manager.h"
|
||||
#include "native_mate/handle.h"
|
||||
@@ -76,6 +77,8 @@ class Session: public mate::TrackableObject<Session>,
|
||||
void AllowNTLMCredentialsForDomains(const std::string& domains);
|
||||
void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
|
||||
std::string GetUserAgent();
|
||||
void GetBlobData(const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback);
|
||||
v8::Local<v8::Value> Cookies(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> Protocol(v8::Isolate* isolate);
|
||||
v8::Local<v8::Value> WebRequest(v8::Isolate* isolate);
|
||||
|
||||
@@ -8,34 +8,36 @@
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/base/win/shell.h"
|
||||
#endif
|
||||
#include "ui/gfx/color_utils.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
SystemPreferences::SystemPreferences(v8::Isolate* isolate) {
|
||||
SystemPreferences::SystemPreferences(v8::Isolate* isolate)
|
||||
#if defined(OS_WIN)
|
||||
: color_change_listener_(this)
|
||||
#endif
|
||||
{
|
||||
Init(isolate);
|
||||
#if defined(OS_WIN)
|
||||
InitializeWindow();
|
||||
#endif
|
||||
}
|
||||
|
||||
SystemPreferences::~SystemPreferences() {
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
bool SystemPreferences::IsDarkMode() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SystemPreferences::IsInvertedColorScheme() {
|
||||
return color_utils::IsInvertedColorScheme();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<SystemPreferences> SystemPreferences::Create(
|
||||
v8::Isolate* isolate) {
|
||||
@@ -48,7 +50,9 @@ void SystemPreferences::BuildPrototype(
|
||||
prototype->SetClassName(mate::StringToV8(isolate, "SystemPreferences"));
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
#if defined(OS_WIN)
|
||||
.SetMethod("getAccentColor", &SystemPreferences::GetAccentColor)
|
||||
.SetMethod("isAeroGlassEnabled", &SystemPreferences::IsAeroGlassEnabled)
|
||||
.SetMethod("getColor", &SystemPreferences::GetColor)
|
||||
#elif defined(OS_MACOSX)
|
||||
.SetMethod("postNotification",
|
||||
&SystemPreferences::PostNotification)
|
||||
@@ -66,6 +70,8 @@ void SystemPreferences::BuildPrototype(
|
||||
.SetMethod("isSwipeTrackingFromScrollEventsEnabled",
|
||||
&SystemPreferences::IsSwipeTrackingFromScrollEventsEnabled)
|
||||
#endif
|
||||
.SetMethod("isInvertedColorScheme",
|
||||
&SystemPreferences::IsInvertedColorScheme)
|
||||
.SetMethod("isDarkMode", &SystemPreferences::IsDarkMode);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
#include "base/values.h"
|
||||
#include "native_mate/handle.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/gfx/sys_color_change_listener.h"
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
}
|
||||
@@ -20,7 +24,11 @@ namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
class SystemPreferences : public mate::EventEmitter<SystemPreferences>
|
||||
#if defined(OS_WIN)
|
||||
, public gfx::SysColorChangeListener
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
static mate::Handle<SystemPreferences> Create(v8::Isolate* isolate);
|
||||
|
||||
@@ -29,6 +37,20 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
bool IsAeroGlassEnabled();
|
||||
|
||||
typedef HRESULT (STDAPICALLTYPE *DwmGetColorizationColor)(DWORD *, BOOL *);
|
||||
DwmGetColorizationColor dwmGetColorizationColor =
|
||||
(DwmGetColorizationColor) GetProcAddress(LoadLibraryW(L"dwmapi.dll"),
|
||||
"DwmGetColorizationColor");
|
||||
|
||||
std::string GetAccentColor();
|
||||
std::string GetColor(const std::string& color, mate::Arguments* args);
|
||||
|
||||
void InitializeWindow();
|
||||
|
||||
// gfx::SysColorChangeListener:
|
||||
void OnSysColorChange() override;
|
||||
|
||||
#elif defined(OS_MACOSX)
|
||||
using NotificationCallback = base::Callback<
|
||||
void(const std::string&, const base::DictionaryValue&)>;
|
||||
@@ -48,6 +70,7 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
bool IsSwipeTrackingFromScrollEventsEnabled();
|
||||
#endif
|
||||
bool IsDarkMode();
|
||||
bool IsInvertedColorScheme();
|
||||
|
||||
protected:
|
||||
explicit SystemPreferences(v8::Isolate* isolate);
|
||||
@@ -64,6 +87,29 @@ class SystemPreferences : public mate::EventEmitter<SystemPreferences> {
|
||||
#endif
|
||||
|
||||
private:
|
||||
#if defined(OS_WIN)
|
||||
// Static callback invoked when a message comes in to our messaging window.
|
||||
static LRESULT CALLBACK
|
||||
WndProcStatic(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
LRESULT CALLBACK
|
||||
WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
// The window class of |window_|.
|
||||
ATOM atom_;
|
||||
|
||||
// The handle of the module that contains the window procedure of |window_|.
|
||||
HMODULE instance_;
|
||||
|
||||
// The window used for processing events.
|
||||
HWND window_;
|
||||
|
||||
std::string current_color_;
|
||||
|
||||
bool invertered_color_scheme_;
|
||||
|
||||
gfx::ScopedSysColorChangeListener color_change_listener_;
|
||||
#endif
|
||||
DISALLOW_COPY_AND_ASSIGN(SystemPreferences);
|
||||
};
|
||||
|
||||
|
||||
177
atom/browser/api/atom_api_system_preferences_win.cc
Normal file
177
atom/browser/api/atom_api_system_preferences_win.cc
Normal file
@@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/api/atom_api_system_preferences.h"
|
||||
|
||||
#include "atom/common/color_util.h"
|
||||
#include "base/win/wrapped_window_proc.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
const wchar_t kSystemPreferencesWindowClass[] =
|
||||
L"Electron_SystemPreferencesHostWindow";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace api {
|
||||
|
||||
bool SystemPreferences::IsAeroGlassEnabled() {
|
||||
return ui::win::IsAeroGlassEnabled();
|
||||
}
|
||||
|
||||
std::string hexColorDWORDToRGBA(DWORD color) {
|
||||
std::ostringstream stream;
|
||||
stream << std::hex << color;
|
||||
std::string hexColor = stream.str();
|
||||
return hexColor.substr(2) + hexColor.substr(0, 2);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetAccentColor() {
|
||||
DWORD color = 0;
|
||||
BOOL opaque = FALSE;
|
||||
|
||||
if (FAILED(dwmGetColorizationColor(&color, &opaque))) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return hexColorDWORDToRGBA(color);
|
||||
}
|
||||
|
||||
std::string SystemPreferences::GetColor(const std::string& color,
|
||||
mate::Arguments* args) {
|
||||
int id;
|
||||
if (color == "3d-dark-shadow") {
|
||||
id = COLOR_3DDKSHADOW;
|
||||
} else if (color == "3d-face") {
|
||||
id = COLOR_3DFACE;
|
||||
} else if (color == "3d-highlight") {
|
||||
id = COLOR_3DHIGHLIGHT;
|
||||
} else if (color == "3d-light") {
|
||||
id = COLOR_3DLIGHT;
|
||||
} else if (color == "3d-shadow") {
|
||||
id = COLOR_3DSHADOW;
|
||||
} else if (color == "active-border") {
|
||||
id = COLOR_ACTIVEBORDER;
|
||||
} else if (color == "active-caption") {
|
||||
id = COLOR_ACTIVECAPTION;
|
||||
} else if (color == "active-caption-gradient") {
|
||||
id = COLOR_GRADIENTACTIVECAPTION;
|
||||
} else if (color == "app-workspace") {
|
||||
id = COLOR_APPWORKSPACE;
|
||||
} else if (color == "button-text") {
|
||||
id = COLOR_BTNTEXT;
|
||||
} else if (color == "caption-text") {
|
||||
id = COLOR_CAPTIONTEXT;
|
||||
} else if (color == "desktop") {
|
||||
id = COLOR_DESKTOP;
|
||||
} else if (color == "disabled-text") {
|
||||
id = COLOR_GRAYTEXT;
|
||||
} else if (color == "highlight") {
|
||||
id = COLOR_HIGHLIGHT;
|
||||
} else if (color == "highlight-text") {
|
||||
id = COLOR_HIGHLIGHTTEXT;
|
||||
} else if (color == "hotlight") {
|
||||
id = COLOR_HOTLIGHT;
|
||||
} else if (color == "inactive-border") {
|
||||
id = COLOR_INACTIVEBORDER;
|
||||
} else if (color == "inactive-caption") {
|
||||
id = COLOR_INACTIVECAPTION;
|
||||
} else if (color == "inactive-caption-gradient") {
|
||||
id = COLOR_GRADIENTINACTIVECAPTION;
|
||||
} else if (color == "inactive-caption-text") {
|
||||
id = COLOR_INACTIVECAPTIONTEXT;
|
||||
} else if (color == "info-background") {
|
||||
id = COLOR_INFOBK;
|
||||
} else if (color == "info-text") {
|
||||
id = COLOR_INFOTEXT;
|
||||
} else if (color == "menu") {
|
||||
id = COLOR_MENU;
|
||||
} else if (color == "menu-highlight") {
|
||||
id = COLOR_MENUHILIGHT;
|
||||
} else if (color == "menubar") {
|
||||
id = COLOR_MENUBAR;
|
||||
} else if (color == "menu-text") {
|
||||
id = COLOR_MENUTEXT;
|
||||
} else if (color == "scrollbar") {
|
||||
id = COLOR_SCROLLBAR;
|
||||
} else if (color == "window") {
|
||||
id = COLOR_WINDOW;
|
||||
} else if (color == "window-frame") {
|
||||
id = COLOR_WINDOWFRAME;
|
||||
} else if (color == "window-text") {
|
||||
id = COLOR_WINDOWTEXT;
|
||||
} else {
|
||||
args->ThrowError("Unknown color: " + color);
|
||||
return "";
|
||||
}
|
||||
|
||||
return ToRGBHex(color_utils::GetSysSkColor(id));
|
||||
}
|
||||
|
||||
void SystemPreferences::InitializeWindow() {
|
||||
invertered_color_scheme_ = IsInvertedColorScheme();
|
||||
|
||||
WNDCLASSEX window_class;
|
||||
base::win::InitializeWindowClass(
|
||||
kSystemPreferencesWindowClass,
|
||||
&base::win::WrappedWindowProc<SystemPreferences::WndProcStatic>,
|
||||
0, 0, 0, NULL, NULL, NULL, NULL, NULL,
|
||||
&window_class);
|
||||
instance_ = window_class.hInstance;
|
||||
atom_ = RegisterClassEx(&window_class);
|
||||
|
||||
// Create an offscreen window for receiving broadcast messages for the system
|
||||
// colorization color. Create a hidden WS_POPUP window instead of an
|
||||
// HWND_MESSAGE window, because only top-level windows such as popups can
|
||||
// receive broadcast messages like "WM_DWMCOLORIZATIONCOLORCHANGED".
|
||||
window_ = CreateWindow(MAKEINTATOM(atom_),
|
||||
0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
|
||||
gfx::CheckWindowCreated(window_);
|
||||
gfx::SetWindowUserData(window_, this);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SystemPreferences::WndProcStatic(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
SystemPreferences* msg_wnd = reinterpret_cast<SystemPreferences*>(
|
||||
GetWindowLongPtr(hwnd, GWLP_USERDATA));
|
||||
if (msg_wnd)
|
||||
return msg_wnd->WndProc(hwnd, message, wparam, lparam);
|
||||
else
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SystemPreferences::WndProc(HWND hwnd,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
if (message == WM_DWMCOLORIZATIONCOLORCHANGED) {
|
||||
DWORD new_color = (DWORD) wparam;
|
||||
std::string new_color_string = hexColorDWORDToRGBA(new_color);
|
||||
if (new_color_string != current_color_) {
|
||||
Emit("accent-color-changed", hexColorDWORDToRGBA(new_color));
|
||||
current_color_ = new_color_string;
|
||||
}
|
||||
}
|
||||
return ::DefWindowProc(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
void SystemPreferences::OnSysColorChange() {
|
||||
bool new_invertered_color_scheme = IsInvertedColorScheme();
|
||||
if (new_invertered_color_scheme != invertered_color_scheme_) {
|
||||
invertered_color_scheme_ = new_invertered_color_scheme;
|
||||
Emit("inverted-color-scheme-changed", new_invertered_color_scheme);
|
||||
}
|
||||
Emit("color-changed");
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@@ -77,6 +76,8 @@
|
||||
#include "ui/aura/window.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct PrintSettings {
|
||||
@@ -133,6 +134,7 @@ struct Converter<WindowOpenDisposition> {
|
||||
case NEW_FOREGROUND_TAB: disposition = "foreground-tab"; break;
|
||||
case NEW_BACKGROUND_TAB: disposition = "background-tab"; break;
|
||||
case NEW_POPUP: case NEW_WINDOW: disposition = "new-window"; break;
|
||||
case SAVE_TO_DISK: disposition = "save-to-disk"; break;
|
||||
default: break;
|
||||
}
|
||||
return mate::ConvertToV8(isolate, disposition);
|
||||
@@ -256,17 +258,25 @@ void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback,
|
||||
} // namespace
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents)
|
||||
content::WebContents* web_contents,
|
||||
Type type)
|
||||
: content::WebContentsObserver(web_contents),
|
||||
embedder_(nullptr),
|
||||
type_(REMOTE),
|
||||
type_(type),
|
||||
request_id_(0),
|
||||
background_throttling_(true),
|
||||
enable_devtools_(true) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
|
||||
Init(isolate);
|
||||
AttachAsUserData(web_contents);
|
||||
if (type == REMOTE) {
|
||||
web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
|
||||
Init(isolate);
|
||||
AttachAsUserData(web_contents);
|
||||
} else {
|
||||
const mate::Dictionary options = mate::Dictionary::CreateEmpty(isolate);
|
||||
auto session = Session::CreateFrom(isolate, GetBrowserContext());
|
||||
session_.Reset(isolate, session.ToV8());
|
||||
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
||||
}
|
||||
}
|
||||
|
||||
WebContents::WebContents(v8::Isolate* isolate,
|
||||
@@ -334,6 +344,13 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
web_contents = content::WebContents::Create(params);
|
||||
}
|
||||
|
||||
InitWithSessionAndOptions(isolate, web_contents, session, options);
|
||||
}
|
||||
|
||||
void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
content::WebContents *web_contents,
|
||||
mate::Handle<api::Session> session,
|
||||
const mate::Dictionary& options) {
|
||||
Observe(web_contents);
|
||||
InitWithWebContents(web_contents, session->browser_context());
|
||||
|
||||
@@ -399,11 +416,37 @@ bool WebContents::AddMessageToConsole(content::WebContents* source,
|
||||
|
||||
void WebContents::OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition) {
|
||||
WindowOpenDisposition disposition,
|
||||
const std::vector<base::string16>& features) {
|
||||
if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN)
|
||||
Emit("-new-window", target_url, frame_name, disposition);
|
||||
Emit("-new-window", target_url, frame_name, disposition, features);
|
||||
else
|
||||
Emit("new-window", target_url, frame_name, disposition);
|
||||
Emit("new-window", target_url, frame_name, disposition, features);
|
||||
}
|
||||
|
||||
void WebContents::WebContentsCreated(content::WebContents* source_contents,
|
||||
int opener_render_frame_id,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
content::WebContents* new_contents) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto api_web_contents = CreateFrom(isolate(), new_contents, BROWSER_WINDOW);
|
||||
Emit("-web-contents-created", api_web_contents, target_url, frame_name);
|
||||
}
|
||||
|
||||
void WebContents::AddNewContents(content::WebContents* source,
|
||||
content::WebContents* new_contents,
|
||||
WindowOpenDisposition disposition,
|
||||
const gfx::Rect& initial_rect,
|
||||
bool user_gesture,
|
||||
bool* was_blocked) {
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
auto api_web_contents = CreateFrom(isolate(), new_contents);
|
||||
Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
|
||||
initial_rect.x(), initial_rect.y(), initial_rect.width(),
|
||||
initial_rect.height());
|
||||
}
|
||||
|
||||
content::WebContents* WebContents::OpenURLFromTab(
|
||||
@@ -527,22 +570,18 @@ void WebContents::FindReply(content::WebContents* web_contents,
|
||||
const gfx::Rect& selection_rect,
|
||||
int active_match_ordinal,
|
||||
bool final_update) {
|
||||
if (!final_update)
|
||||
return;
|
||||
|
||||
v8::Locker locker(isolate());
|
||||
v8::HandleScope handle_scope(isolate());
|
||||
|
||||
mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
|
||||
if (number_of_matches == -1) {
|
||||
result.Set("requestId", request_id);
|
||||
result.Set("selectionArea", selection_rect);
|
||||
result.Set("finalUpdate", final_update);
|
||||
result.Set("activeMatchOrdinal", active_match_ordinal);
|
||||
Emit("found-in-page", result);
|
||||
} else if (final_update) {
|
||||
result.Set("requestId", request_id);
|
||||
result.Set("matches", number_of_matches);
|
||||
result.Set("finalUpdate", final_update);
|
||||
Emit("found-in-page", result);
|
||||
}
|
||||
result.Set("requestId", request_id);
|
||||
result.Set("matches", number_of_matches);
|
||||
result.Set("selectionArea", selection_rect);
|
||||
result.Set("activeMatchOrdinal", active_match_ordinal);
|
||||
result.Set("finalUpdate", final_update); // Deprecate after 2.0
|
||||
Emit("found-in-page", result);
|
||||
}
|
||||
|
||||
bool WebContents::CheckMediaAccessPermission(
|
||||
@@ -588,7 +627,7 @@ void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
|
||||
}
|
||||
|
||||
void WebContents::RenderProcessGone(base::TerminationStatus status) {
|
||||
Emit("crashed");
|
||||
Emit("crashed", status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED);
|
||||
}
|
||||
|
||||
void WebContents::PluginCrashed(const base::FilePath& plugin_path,
|
||||
@@ -608,11 +647,7 @@ void WebContents::MediaStoppedPlaying(const MediaPlayerId& id) {
|
||||
}
|
||||
|
||||
void WebContents::DidChangeThemeColor(SkColor theme_color) {
|
||||
std::string hex_theme_color = base::StringPrintf("#%02X%02X%02X",
|
||||
SkColorGetR(theme_color),
|
||||
SkColorGetG(theme_color),
|
||||
SkColorGetB(theme_color));
|
||||
Emit("did-change-theme-color", hex_theme_color);
|
||||
Emit("did-change-theme-color", atom::ToRGBHex(theme_color));
|
||||
}
|
||||
|
||||
void WebContents::DocumentLoadedInFrame(
|
||||
@@ -803,7 +838,14 @@ void WebContents::NavigationEntryCommitted(
|
||||
details.is_in_page, details.did_replace_entry);
|
||||
}
|
||||
|
||||
int WebContents::GetID() const {
|
||||
int64_t WebContents::GetID() const {
|
||||
int64_t process_id = web_contents()->GetRenderProcessHost()->GetID();
|
||||
int64_t routing_id = web_contents()->GetRoutingID();
|
||||
int64_t rv = (process_id << 32) + routing_id;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int WebContents::GetProcessID() const {
|
||||
return web_contents()->GetRenderProcessHost()->GetID();
|
||||
}
|
||||
|
||||
@@ -871,7 +913,8 @@ void WebContents::DownloadURL(const GURL& url) {
|
||||
content::BrowserContext::GetDownloadManager(browser_context);
|
||||
|
||||
download_manager->DownloadUrl(
|
||||
content::DownloadUrlParameters::FromWebContents(web_contents(), url));
|
||||
content::DownloadUrlParameters::CreateForWebContentsMainFrame(
|
||||
web_contents(), url));
|
||||
}
|
||||
|
||||
GURL WebContents::GetURL() const {
|
||||
@@ -1177,7 +1220,7 @@ void WebContents::ShowDefinitionForSelection() {
|
||||
}
|
||||
|
||||
void WebContents::CopyImageAt(int x, int y) {
|
||||
const auto host = web_contents()->GetRenderViewHost();
|
||||
const auto host = web_contents()->GetMainFrame();
|
||||
if (host)
|
||||
host->CopyImageAt(x, y);
|
||||
}
|
||||
@@ -1419,6 +1462,15 @@ int WebContents::GetFrameRate() const {
|
||||
return osr_rwhv ? osr_rwhv->GetFrameRate() : 0;
|
||||
}
|
||||
|
||||
void WebContents::Invalidate() {
|
||||
if (!IsOffScreen())
|
||||
return;
|
||||
|
||||
auto* osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
|
||||
web_contents()->GetRenderWidgetHostView());
|
||||
if (osr_rwhv)
|
||||
osr_rwhv->Invalidate();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
|
||||
WebContentsPreferences* web_preferences =
|
||||
@@ -1447,6 +1499,25 @@ content::WebContents* WebContents::HostWebContents() {
|
||||
return embedder_->web_contents();
|
||||
}
|
||||
|
||||
void WebContents::SetEmbedder(const WebContents* embedder) {
|
||||
if (embedder) {
|
||||
NativeWindow* owner_window = nullptr;
|
||||
auto relay = NativeWindowRelay::FromWebContents(embedder->web_contents());
|
||||
if (relay) {
|
||||
owner_window = relay->window.get();
|
||||
}
|
||||
if (owner_window)
|
||||
SetOwnerWindow(owner_window);
|
||||
|
||||
content::RenderWidgetHostView* rwhv =
|
||||
web_contents()->GetRenderWidgetHostView();
|
||||
if (rwhv) {
|
||||
rwhv->Hide();
|
||||
rwhv->Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> WebContents::DevToolsWebContents(v8::Isolate* isolate) {
|
||||
if (devtools_web_contents_.IsEmpty())
|
||||
return v8::Null(isolate);
|
||||
@@ -1469,6 +1540,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
|
||||
.MakeDestroyable()
|
||||
.SetMethod("getId", &WebContents::GetID)
|
||||
.SetMethod("getProcessId", &WebContents::GetProcessID)
|
||||
.SetMethod("equal", &WebContents::Equal)
|
||||
.SetMethod("_loadURL", &WebContents::LoadURL)
|
||||
.SetMethod("downloadURL", &WebContents::DownloadURL)
|
||||
@@ -1528,6 +1600,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
.SetMethod("isPainting", &WebContents::IsPainting)
|
||||
.SetMethod("setFrameRate", &WebContents::SetFrameRate)
|
||||
.SetMethod("getFrameRate", &WebContents::GetFrameRate)
|
||||
.SetMethod("invalidate", &WebContents::Invalidate)
|
||||
.SetMethod("getType", &WebContents::GetType)
|
||||
.SetMethod("getWebPreferences", &WebContents::GetWebPreferences)
|
||||
.SetMethod("getOwnerBrowserWindow", &WebContents::GetOwnerBrowserWindow)
|
||||
@@ -1543,6 +1616,7 @@ void WebContents::BuildPrototype(v8::Isolate* isolate,
|
||||
&WebContents::ShowDefinitionForSelection)
|
||||
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
|
||||
.SetMethod("capturePage", &WebContents::CapturePage)
|
||||
.SetMethod("setEmbedder", &WebContents::SetEmbedder)
|
||||
.SetProperty("id", &WebContents::ID)
|
||||
.SetProperty("session", &WebContents::Session)
|
||||
.SetProperty("hostWebContents", &WebContents::HostWebContents)
|
||||
@@ -1576,7 +1650,15 @@ mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
return mate::CreateHandle(isolate, static_cast<WebContents*>(existing));
|
||||
|
||||
// Otherwise create a new WebContents wrapper object.
|
||||
return mate::CreateHandle(isolate, new WebContents(isolate, web_contents));
|
||||
return mate::CreateHandle(isolate, new WebContents(isolate, web_contents,
|
||||
REMOTE));
|
||||
}
|
||||
|
||||
mate::Handle<WebContents> WebContents::CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents, Type type) {
|
||||
// Otherwise create a new WebContents wrapper object.
|
||||
return mate::CreateHandle(isolate, new WebContents(isolate, web_contents,
|
||||
type));
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -58,6 +58,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Create from an existing WebContents.
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
static mate::Handle<WebContents> CreateFrom(
|
||||
v8::Isolate* isolate, content::WebContents* web_contents, Type type);
|
||||
|
||||
// Create a new WebContents.
|
||||
static mate::Handle<WebContents> Create(
|
||||
@@ -66,7 +68,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
v8::Local<v8::FunctionTemplate> prototype);
|
||||
|
||||
int GetID() const;
|
||||
int64_t GetID() const;
|
||||
int GetProcessID() const;
|
||||
Type GetType() const;
|
||||
bool Equal(const WebContents* web_contents) const;
|
||||
void LoadURL(const GURL& url, const mate::Dictionary& options);
|
||||
@@ -102,6 +105,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
void SetAudioMuted(bool muted);
|
||||
bool IsAudioMuted();
|
||||
void Print(mate::Arguments* args);
|
||||
void SetEmbedder(const WebContents* embedder);
|
||||
|
||||
// Print current page as PDF.
|
||||
void PrintToPDF(const base::DictionaryValue& setting,
|
||||
@@ -164,6 +168,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
bool IsPainting() const;
|
||||
void SetFrameRate(int frame_rate);
|
||||
int GetFrameRate() const;
|
||||
void Invalidate();
|
||||
|
||||
// Callback triggered on permission response.
|
||||
void OnEnterFullscreenModeForTab(content::WebContents* source,
|
||||
@@ -173,7 +178,8 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
// Create window with the given disposition.
|
||||
void OnCreateWindow(const GURL& target_url,
|
||||
const std::string& frame_name,
|
||||
WindowOpenDisposition disposition);
|
||||
WindowOpenDisposition disposition,
|
||||
const std::vector<base::string16>& features);
|
||||
|
||||
// Returns the web preferences of current WebContents.
|
||||
v8::Local<v8::Value> GetWebPreferences(v8::Isolate* isolate);
|
||||
@@ -189,16 +195,34 @@ class WebContents : public mate::TrackableObject<WebContents>,
|
||||
v8::Local<v8::Value> Debugger(v8::Isolate* isolate);
|
||||
|
||||
protected:
|
||||
WebContents(v8::Isolate* isolate, content::WebContents* web_contents);
|
||||
WebContents(v8::Isolate* isolate,
|
||||
content::WebContents* web_contents,
|
||||
Type type);
|
||||
WebContents(v8::Isolate* isolate, const mate::Dictionary& options);
|
||||
~WebContents();
|
||||
|
||||
void InitWithSessionAndOptions(v8::Isolate* isolate,
|
||||
content::WebContents *web_contents,
|
||||
mate::Handle<class Session> session,
|
||||
const mate::Dictionary& options);
|
||||
|
||||
// content::WebContentsDelegate:
|
||||
bool AddMessageToConsole(content::WebContents* source,
|
||||
int32_t level,
|
||||
const base::string16& message,
|
||||
int32_t line_no,
|
||||
const base::string16& source_id) override;
|
||||
void WebContentsCreated(content::WebContents* source_contents,
|
||||
int opener_render_frame_id,
|
||||
const std::string& frame_name,
|
||||
const GURL& target_url,
|
||||
content::WebContents* new_contents) override;
|
||||
void AddNewContents(content::WebContents* source,
|
||||
content::WebContents* new_contents,
|
||||
WindowOpenDisposition disposition,
|
||||
const gfx::Rect& initial_rect,
|
||||
bool user_gesture,
|
||||
bool* was_blocked) override;
|
||||
content::WebContents* OpenURLFromTab(
|
||||
content::WebContents* source,
|
||||
const content::OpenURLParams& params) override;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/options_switches.h"
|
||||
#include "base/command_line.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
@@ -31,6 +30,8 @@
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
namespace mate {
|
||||
|
||||
@@ -71,20 +72,33 @@ v8::Local<v8::Value> ToBuffer(v8::Isolate* isolate, void* val, int size) {
|
||||
|
||||
Window::Window(v8::Isolate* isolate, v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options) {
|
||||
// Use options.webPreferences to create WebContents.
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
mate::Handle<class WebContents> web_contents;
|
||||
// If no WebContents was passed to the constructor, create it from options.
|
||||
if (!options.Get("webContents", &web_contents)) {
|
||||
// Use options.webPreferences to create WebContents.
|
||||
mate::Dictionary web_preferences = mate::Dictionary::CreateEmpty(isolate);
|
||||
options.Get(options::kWebPreferences, &web_preferences);
|
||||
|
||||
// Copy the backgroundColor to webContents.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get(options::kBackgroundColor, &value))
|
||||
web_preferences.Set(options::kBackgroundColor, value);
|
||||
// Copy the backgroundColor to webContents.
|
||||
v8::Local<v8::Value> value;
|
||||
if (options.Get(options::kBackgroundColor, &value))
|
||||
web_preferences.Set(options::kBackgroundColor, value);
|
||||
|
||||
v8::Local<v8::Value> transparent;
|
||||
if (options.Get("transparent", &transparent))
|
||||
web_preferences.Set("transparent", transparent);
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
auto web_contents = WebContents::Create(isolate, web_preferences);
|
||||
v8::Local<v8::Value> transparent;
|
||||
if (options.Get("transparent", &transparent))
|
||||
web_preferences.Set("transparent", transparent);
|
||||
|
||||
// Creates the WebContents used by BrowserWindow.
|
||||
web_contents = WebContents::Create(isolate, web_preferences);
|
||||
}
|
||||
|
||||
Init(isolate, wrapper, options, web_contents);
|
||||
}
|
||||
|
||||
void Window::Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options,
|
||||
mate::Handle<class WebContents> web_contents) {
|
||||
web_contents_.Reset(isolate, web_contents.ToV8());
|
||||
api_web_contents_ = web_contents.get();
|
||||
|
||||
@@ -229,6 +243,10 @@ void Window::OnWindowScrollTouchEnd() {
|
||||
Emit("scroll-touch-end");
|
||||
}
|
||||
|
||||
void Window::OnWindowScrollTouchEdge() {
|
||||
Emit("scroll-touch-edge");
|
||||
}
|
||||
|
||||
void Window::OnWindowSwipe(const std::string& direction) {
|
||||
Emit("swipe", direction);
|
||||
}
|
||||
@@ -481,8 +499,10 @@ bool Window::IsClosable() {
|
||||
return window_->IsClosable();
|
||||
}
|
||||
|
||||
void Window::SetAlwaysOnTop(bool top) {
|
||||
window_->SetAlwaysOnTop(top);
|
||||
void Window::SetAlwaysOnTop(bool top, mate::Arguments* args) {
|
||||
std::string level = "floating";
|
||||
args->GetNext(&level);
|
||||
window_->SetAlwaysOnTop(top, level);
|
||||
}
|
||||
|
||||
bool Window::IsAlwaysOnTop() {
|
||||
|
||||
@@ -74,6 +74,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
void OnWindowMoved() override;
|
||||
void OnWindowScrollTouchBegin() override;
|
||||
void OnWindowScrollTouchEnd() override;
|
||||
void OnWindowScrollTouchEdge() override;
|
||||
void OnWindowSwipe(const std::string& direction) override;
|
||||
void OnWindowEnterFullScreen() override;
|
||||
void OnWindowLeaveFullScreen() override;
|
||||
@@ -88,6 +89,10 @@ class Window : public mate::TrackableObject<Window>,
|
||||
#endif
|
||||
|
||||
private:
|
||||
void Init(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper,
|
||||
const mate::Dictionary& options,
|
||||
mate::Handle<class WebContents> web_contents);
|
||||
// APIs for NativeWindow.
|
||||
void Close();
|
||||
void Focus();
|
||||
@@ -131,7 +136,7 @@ class Window : public mate::TrackableObject<Window>,
|
||||
bool IsFullScreenable();
|
||||
void SetClosable(bool closable);
|
||||
bool IsClosable();
|
||||
void SetAlwaysOnTop(bool top);
|
||||
void SetAlwaysOnTop(bool top, mate::Arguments* args);
|
||||
bool IsAlwaysOnTop();
|
||||
void Center();
|
||||
void SetPosition(int x, int y, mate::Arguments* args);
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
#include "atom/browser/api/frame_subscriber.h"
|
||||
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "base/bind.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -40,6 +43,17 @@ bool FrameSubscriber::ShouldCaptureFrame(
|
||||
if (only_dirty_)
|
||||
rect = dirty_rect;
|
||||
|
||||
gfx::Size view_size = rect.size();
|
||||
gfx::Size bitmap_size = view_size;
|
||||
const gfx::NativeView native_view = view_->GetNativeView();
|
||||
const float scale =
|
||||
display::Screen::GetScreen()->GetDisplayNearestWindow(native_view)
|
||||
.device_scale_factor();
|
||||
if (scale > 1.0f)
|
||||
bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
|
||||
|
||||
rect = gfx::Rect(rect.origin(), bitmap_size);
|
||||
|
||||
host->CopyFromBackingStore(
|
||||
rect,
|
||||
rect.size(),
|
||||
|
||||
@@ -4,23 +4,67 @@
|
||||
|
||||
#include "atom/browser/atom_access_token_store.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
#include "atom/common/google_api_key.h"
|
||||
#include "base/environment.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/geolocation_provider.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
// Notice that we just combined the api key with the url together here, because
|
||||
// if we use the standard {url: key} format Chromium would override our key with
|
||||
// the predefined one in common.gypi of libchromiumcontent, which is empty.
|
||||
const char* kGeolocationProviderURL =
|
||||
"https://www.googleapis.com/geolocation/v1/geolocate?key="
|
||||
GOOGLEAPIS_API_KEY;
|
||||
// Loads access tokens and other necessary data on the UI thread, and
|
||||
// calls back to the originator on the originating thread.
|
||||
class TokenLoadingJob : public base::RefCountedThreadSafe<TokenLoadingJob> {
|
||||
public:
|
||||
explicit TokenLoadingJob(
|
||||
const content::AccessTokenStore::LoadAccessTokensCallback& callback)
|
||||
: callback_(callback), request_context_getter_(nullptr) {}
|
||||
|
||||
void Run() {
|
||||
BrowserThread::PostTaskAndReply(
|
||||
BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&TokenLoadingJob::PerformWorkOnUIThread, this),
|
||||
base::Bind(&TokenLoadingJob::RespondOnOriginatingThread, this));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class base::RefCountedThreadSafe<TokenLoadingJob>;
|
||||
|
||||
~TokenLoadingJob() {}
|
||||
|
||||
void PerformWorkOnUIThread() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
auto browser_context = AtomBrowserContext::From("", false);
|
||||
request_context_getter_ = browser_context->GetRequestContext();
|
||||
std::unique_ptr<base::Environment> env(base::Environment::Create());
|
||||
if (!env->GetVar("GOOGLE_API_KEY", &api_key_))
|
||||
api_key_ = GOOGLEAPIS_API_KEY;
|
||||
}
|
||||
|
||||
void RespondOnOriginatingThread() {
|
||||
// Equivalent to access_token_map[kGeolocationProviderURL].
|
||||
// Somehow base::string16 is causing compilation errors when used in a pair
|
||||
// of std::map on Linux, this can work around it.
|
||||
content::AccessTokenStore::AccessTokenMap access_token_map;
|
||||
std::pair<GURL, base::string16> token_pair;
|
||||
token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key_);
|
||||
access_token_map.insert(token_pair);
|
||||
|
||||
callback_.Run(access_token_map, request_context_getter_);
|
||||
}
|
||||
|
||||
content::AccessTokenStore::LoadAccessTokensCallback callback_;
|
||||
net::URLRequestContextGetter* request_context_getter_;
|
||||
std::string api_key_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -33,35 +77,12 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
|
||||
|
||||
void AtomAccessTokenStore::LoadAccessTokens(
|
||||
const LoadAccessTokensCallback& callback) {
|
||||
content::BrowserThread::PostTaskAndReply(
|
||||
content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&AtomAccessTokenStore::GetRequestContextOnUIThread, this),
|
||||
base::Bind(&AtomAccessTokenStore::RespondOnOriginatingThread,
|
||||
this, callback));
|
||||
scoped_refptr<TokenLoadingJob> job(new TokenLoadingJob(callback));
|
||||
job->Run();
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
|
||||
const base::string16& access_token) {
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::GetRequestContextOnUIThread() {
|
||||
auto browser_context = AtomBrowserContext::From("", false);
|
||||
request_context_getter_ = browser_context->GetRequestContext();
|
||||
}
|
||||
|
||||
void AtomAccessTokenStore::RespondOnOriginatingThread(
|
||||
const LoadAccessTokensCallback& callback) {
|
||||
// Equivelent to access_token_map[kGeolocationProviderURL].
|
||||
// Somehow base::string16 is causing compilation errors when used in a pair
|
||||
// of std::map on Linux, this can work around it.
|
||||
AccessTokenMap access_token_map;
|
||||
std::pair<GURL, base::string16> token_pair;
|
||||
token_pair.first = GURL(kGeolocationProviderURL);
|
||||
access_token_map.insert(token_pair);
|
||||
|
||||
callback.Run(access_token_map, request_context_getter_.get());
|
||||
request_context_getter_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -21,11 +21,6 @@ class AtomAccessTokenStore : public content::AccessTokenStore {
|
||||
const base::string16& access_token) override;
|
||||
|
||||
private:
|
||||
void GetRequestContextOnUIThread();
|
||||
void RespondOnOriginatingThread(const LoadAccessTokensCallback& callback);
|
||||
|
||||
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
|
||||
};
|
||||
|
||||
|
||||
138
atom/browser/atom_blob_reader.cc
Normal file
138
atom/browser/atom_blob_reader.cc
Normal file
@@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
|
||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/io_buffer.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "storage/browser/blob/blob_data_handle.h"
|
||||
#include "storage/browser/blob/blob_reader.h"
|
||||
#include "storage/browser/blob/blob_storage_context.h"
|
||||
#include "storage/browser/fileapi/file_system_context.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace {
|
||||
|
||||
void FreeNodeBufferData(char* data, void* hint) {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void RunCallbackInUI(
|
||||
const AtomBlobReader::CompletionCallback& callback,
|
||||
char* blob_data,
|
||||
int size) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
if (blob_data) {
|
||||
v8::Local<v8::Value> buffer = node::Buffer::New(isolate,
|
||||
blob_data, static_cast<size_t>(size), &FreeNodeBufferData, nullptr)
|
||||
.ToLocalChecked();
|
||||
callback.Run(buffer);
|
||||
} else {
|
||||
callback.Run(v8::Null(isolate));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AtomBlobReader::AtomBlobReader(
|
||||
content::ChromeBlobStorageContext* blob_context,
|
||||
storage::FileSystemContext* file_system_context)
|
||||
: blob_context_(blob_context),
|
||||
file_system_context_(file_system_context) {
|
||||
}
|
||||
|
||||
AtomBlobReader::~AtomBlobReader() {
|
||||
}
|
||||
|
||||
void AtomBlobReader::StartReading(
|
||||
const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& completion_callback) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
auto blob_data_handle =
|
||||
blob_context_->context()->GetBlobDataFromUUID(uuid);
|
||||
auto callback = base::Bind(&RunCallbackInUI,
|
||||
completion_callback);
|
||||
if (!blob_data_handle) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(callback, nullptr, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
auto blob_reader = blob_data_handle->CreateReader(
|
||||
file_system_context_.get(),
|
||||
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE).get());
|
||||
BlobReadHelper* blob_read_helper =
|
||||
new BlobReadHelper(std::move(blob_reader), callback);
|
||||
blob_read_helper->Read();
|
||||
}
|
||||
|
||||
AtomBlobReader::BlobReadHelper::BlobReadHelper(
|
||||
std::unique_ptr<storage::BlobReader> blob_reader,
|
||||
const BlobReadHelper::CompletionCallback& callback)
|
||||
: blob_reader_(std::move(blob_reader)),
|
||||
completion_callback_(callback) {
|
||||
}
|
||||
|
||||
AtomBlobReader::BlobReadHelper::~BlobReadHelper() {
|
||||
}
|
||||
|
||||
void AtomBlobReader::BlobReadHelper::Read() {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
storage::BlobReader::Status size_status = blob_reader_->CalculateSize(
|
||||
base::Bind(&AtomBlobReader::BlobReadHelper::DidCalculateSize,
|
||||
base::Unretained(this)));
|
||||
if (size_status != storage::BlobReader::Status::IO_PENDING)
|
||||
DidCalculateSize(net::OK);
|
||||
}
|
||||
|
||||
void AtomBlobReader::BlobReadHelper::DidCalculateSize(int result) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
if (result != net::OK) {
|
||||
DidReadBlobData(nullptr, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t total_size = blob_reader_->total_size();
|
||||
int bytes_read = 0;
|
||||
scoped_refptr<net::IOBuffer> blob_data =
|
||||
new net::IOBuffer(static_cast<size_t>(total_size));
|
||||
auto callback = base::Bind(&AtomBlobReader::BlobReadHelper::DidReadBlobData,
|
||||
base::Unretained(this),
|
||||
base::RetainedRef(blob_data));
|
||||
storage::BlobReader::Status read_status = blob_reader_->Read(
|
||||
blob_data.get(),
|
||||
total_size,
|
||||
&bytes_read,
|
||||
callback);
|
||||
if (read_status != storage::BlobReader::Status::IO_PENDING)
|
||||
callback.Run(bytes_read);
|
||||
}
|
||||
|
||||
void AtomBlobReader::BlobReadHelper::DidReadBlobData(
|
||||
const scoped_refptr<net::IOBuffer>& blob_data,
|
||||
int size) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||
|
||||
char* data = new char[size];
|
||||
memcpy(data, blob_data->data(), size);
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(completion_callback_, data, size));
|
||||
delete this;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
80
atom/browser/atom_blob_reader.h
Normal file
80
atom/browser/atom_blob_reader.h
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_ATOM_BLOB_READER_H_
|
||||
#define ATOM_BROWSER_ATOM_BLOB_READER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/callback.h"
|
||||
|
||||
namespace content {
|
||||
class ChromeBlobStorageContext;
|
||||
}
|
||||
|
||||
namespace net {
|
||||
class IOBuffer;
|
||||
}
|
||||
|
||||
namespace storage {
|
||||
class BlobDataHandle;
|
||||
class BlobReader;
|
||||
class FileSystemContext;
|
||||
}
|
||||
|
||||
namespace v8 {
|
||||
template <class T>
|
||||
class Local;
|
||||
class Value;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
// A class to keep track of the blob context. All methods,
|
||||
// except Ctor are expected to be called on IO thread.
|
||||
class AtomBlobReader {
|
||||
public:
|
||||
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
|
||||
|
||||
AtomBlobReader(content::ChromeBlobStorageContext* blob_context,
|
||||
storage::FileSystemContext* file_system_context);
|
||||
~AtomBlobReader();
|
||||
|
||||
void StartReading(
|
||||
const std::string& uuid,
|
||||
const AtomBlobReader::CompletionCallback& callback);
|
||||
|
||||
private:
|
||||
// A self-destroyed helper class to read the blob data.
|
||||
// Must be accessed on IO thread.
|
||||
class BlobReadHelper {
|
||||
public:
|
||||
using CompletionCallback = base::Callback<void(char*, int)>;
|
||||
|
||||
BlobReadHelper(std::unique_ptr<storage::BlobReader> blob_reader,
|
||||
const BlobReadHelper::CompletionCallback& callback);
|
||||
~BlobReadHelper();
|
||||
|
||||
void Read();
|
||||
|
||||
private:
|
||||
void DidCalculateSize(int result);
|
||||
void DidReadBlobData(const scoped_refptr<net::IOBuffer>& blob_data,
|
||||
int bytes_read);
|
||||
|
||||
std::unique_ptr<storage::BlobReader> blob_reader_;
|
||||
BlobReadHelper::CompletionCallback completion_callback_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BlobReadHelper);
|
||||
};
|
||||
|
||||
scoped_refptr<content::ChromeBlobStorageContext> blob_context_;
|
||||
scoped_refptr<storage::FileSystemContext> file_system_context_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBlobReader);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_ATOM_BLOB_READER_H_
|
||||
@@ -32,11 +32,13 @@
|
||||
#include "chrome/browser/speech/tts_message_filter.h"
|
||||
#include "content/public/browser/browser_ppapi_host.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/geolocation_delegate.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/resource_dispatcher_host.h"
|
||||
#include "content/public/browser/site_instance.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "ppapi/host/ppapi_host.h"
|
||||
@@ -53,6 +55,19 @@ bool g_suppress_renderer_process_restart = false;
|
||||
// Custom schemes to be registered to handle service worker.
|
||||
std::string g_custom_service_worker_schemes = "";
|
||||
|
||||
// A provider of Geolocation services to override AccessTokenStore.
|
||||
class AtomGeolocationDelegate : public content::GeolocationDelegate {
|
||||
public:
|
||||
AtomGeolocationDelegate() = default;
|
||||
|
||||
content::AccessTokenStore* CreateAccessTokenStore() final {
|
||||
return new AtomAccessTokenStore();
|
||||
}
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomGeolocationDelegate);
|
||||
};
|
||||
|
||||
void Noop(scoped_refptr<content::SiteInstance>) {
|
||||
}
|
||||
|
||||
@@ -85,6 +100,44 @@ content::WebContents* AtomBrowserClient::GetWebContentsFromProcessID(
|
||||
return WebContentsPreferences::GetWebContentsFromProcessID(process_id);
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::ShouldCreateNewSiteInstance(
|
||||
content::BrowserContext* browser_context,
|
||||
content::SiteInstance* current_instance,
|
||||
const GURL& url) {
|
||||
|
||||
if (url.SchemeIs(url::kJavaScriptScheme))
|
||||
// "javacript:" scheme should always use same SiteInstance
|
||||
return false;
|
||||
|
||||
if (!IsRendererSandboxed(current_instance->GetProcess()->GetID()))
|
||||
// non-sandboxed renderers should always create a new SiteInstance
|
||||
return true;
|
||||
|
||||
// Create new a SiteInstance if navigating to a different site.
|
||||
auto src_url = current_instance->GetSiteURL();
|
||||
return
|
||||
!content::SiteInstance::IsSameWebSite(browser_context, src_url, url) &&
|
||||
// `IsSameWebSite` doesn't seem to work for some URIs such as `file:`,
|
||||
// handle these scenarios by comparing only the site as defined by
|
||||
// `GetSiteForURL`.
|
||||
content::SiteInstance::GetSiteForURL(browser_context, url) != src_url;
|
||||
}
|
||||
|
||||
void AtomBrowserClient::AddSandboxedRendererId(int process_id) {
|
||||
base::AutoLock auto_lock(sandboxed_renderers_lock_);
|
||||
sandboxed_renderers_.insert(process_id);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RemoveSandboxedRendererId(int process_id) {
|
||||
base::AutoLock auto_lock(sandboxed_renderers_lock_);
|
||||
sandboxed_renderers_.erase(process_id);
|
||||
}
|
||||
|
||||
bool AtomBrowserClient::IsRendererSandboxed(int process_id) {
|
||||
base::AutoLock auto_lock(sandboxed_renderers_lock_);
|
||||
return sandboxed_renderers_.count(process_id);
|
||||
}
|
||||
|
||||
void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
content::RenderProcessHost* host) {
|
||||
int process_id = host->GetID();
|
||||
@@ -92,6 +145,13 @@ void AtomBrowserClient::RenderProcessWillLaunch(
|
||||
host->AddFilter(new TtsMessageFilter(process_id, host->GetBrowserContext()));
|
||||
host->AddFilter(
|
||||
new WidevineCdmMessageFilter(process_id, host->GetBrowserContext()));
|
||||
|
||||
content::WebContents* web_contents = GetWebContentsFromProcessID(process_id);
|
||||
if (WebContentsPreferences::IsSandboxed(web_contents)) {
|
||||
AddSandboxedRendererId(host->GetID());
|
||||
// ensure the sandboxed renderer id is removed later
|
||||
host->AddObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
@@ -99,8 +159,9 @@ content::SpeechRecognitionManagerDelegate*
|
||||
return new AtomSpeechRecognitionManagerDelegate;
|
||||
}
|
||||
|
||||
content::AccessTokenStore* AtomBrowserClient::CreateAccessTokenStore() {
|
||||
return new AtomAccessTokenStore;
|
||||
content::GeolocationDelegate*
|
||||
AtomBrowserClient::CreateGeolocationDelegate() {
|
||||
return new AtomGeolocationDelegate();
|
||||
}
|
||||
|
||||
void AtomBrowserClient::OverrideWebkitPrefs(
|
||||
@@ -140,8 +201,7 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation(
|
||||
return;
|
||||
}
|
||||
|
||||
// Restart renderer process for all navigations except "javacript:" scheme.
|
||||
if (url.SchemeIs(url::kJavaScriptScheme))
|
||||
if (!ShouldCreateNewSiteInstance(browser_context, current_instance, url))
|
||||
return;
|
||||
|
||||
scoped_refptr<content::SiteInstance> site_instance =
|
||||
@@ -173,6 +233,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||
// Copy following switches to child process.
|
||||
static const char* const kCommonSwitchNames[] = {
|
||||
switches::kStandardSchemes,
|
||||
switches::kEnableSandbox
|
||||
};
|
||||
command_line->CopySwitchesFrom(
|
||||
*base::CommandLine::ForCurrentProcess(),
|
||||
@@ -257,6 +318,7 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
const content::Referrer& referrer,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::WebWindowFeatures& features,
|
||||
const std::vector<base::string16>& additional_features,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
content::ResourceContext* context,
|
||||
@@ -266,6 +328,11 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
bool* no_javascript_access) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
||||
|
||||
if (IsRendererSandboxed(render_process_id)) {
|
||||
*no_javascript_access = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (delegate_) {
|
||||
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&api::App::OnCreateWindow,
|
||||
@@ -273,6 +340,7 @@ bool AtomBrowserClient::CanCreateWindow(
|
||||
target_url,
|
||||
frame_name,
|
||||
disposition,
|
||||
additional_features,
|
||||
render_process_id,
|
||||
opener_render_frame_id));
|
||||
}
|
||||
@@ -287,6 +355,7 @@ void AtomBrowserClient::GetAdditionalAllowedSchemesForFileSystem(
|
||||
additional_schemes->insert(additional_schemes->end(),
|
||||
schemes_list.begin(),
|
||||
schemes_list.end());
|
||||
additional_schemes->push_back(content::kChromeDevToolsScheme);
|
||||
}
|
||||
|
||||
brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts(
|
||||
@@ -323,6 +392,7 @@ void AtomBrowserClient::RenderProcessHostDestroyed(
|
||||
break;
|
||||
}
|
||||
}
|
||||
RemoveSandboxedRendererId(process_id);
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ATOM_BROWSER_ATOM_BROWSER_CLIENT_H_
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -49,7 +50,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
void RenderProcessWillLaunch(content::RenderProcessHost* host) override;
|
||||
content::SpeechRecognitionManagerDelegate*
|
||||
CreateSpeechRecognitionManagerDelegate() override;
|
||||
content::AccessTokenStore* CreateAccessTokenStore() override;
|
||||
content::GeolocationDelegate* CreateGeolocationDelegate() override;
|
||||
void OverrideWebkitPrefs(content::RenderViewHost* render_view_host,
|
||||
content::WebPreferences* prefs) override;
|
||||
std::string GetApplicationLocale() override;
|
||||
@@ -87,6 +88,7 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
const content::Referrer& referrer,
|
||||
WindowOpenDisposition disposition,
|
||||
const blink::WebWindowFeatures& features,
|
||||
const std::vector<base::string16>& additional_features,
|
||||
bool user_gesture,
|
||||
bool opener_suppressed,
|
||||
content::ResourceContext* context,
|
||||
@@ -108,8 +110,19 @@ class AtomBrowserClient : public brightray::BrowserClient,
|
||||
void RenderProcessHostDestroyed(content::RenderProcessHost* host) override;
|
||||
|
||||
private:
|
||||
bool ShouldCreateNewSiteInstance(content::BrowserContext* browser_context,
|
||||
content::SiteInstance* current_instance,
|
||||
const GURL& dest_url);
|
||||
// Add/remove a process id to `sandboxed_renderers_`.
|
||||
void AddSandboxedRendererId(int process_id);
|
||||
void RemoveSandboxedRendererId(int process_id);
|
||||
bool IsRendererSandboxed(int process_id);
|
||||
|
||||
// pending_render_process => current_render_process.
|
||||
std::map<int, int> pending_processes_;
|
||||
// Set that contains the process ids of all sandboxed renderers
|
||||
std::set<int> sandboxed_renderers_;
|
||||
base::Lock sandboxed_renderers_lock_;
|
||||
|
||||
std::unique_ptr<AtomResourceDispatcherHostDelegate>
|
||||
resource_dispatcher_host_delegate_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "atom/browser/atom_browser_context.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_protocol.h"
|
||||
#include "atom/browser/atom_blob_reader.h"
|
||||
#include "atom/browser/atom_browser_main_parts.h"
|
||||
#include "atom/browser/atom_download_manager_delegate.h"
|
||||
#include "atom/browser/atom_permission_manager.h"
|
||||
@@ -30,7 +31,9 @@
|
||||
#include "chrome/common/chrome_paths.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/pref_registry_simple.h"
|
||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/storage_partition.h"
|
||||
#include "content/public/common/url_constants.h"
|
||||
#include "content/public/common/user_agent.h"
|
||||
#include "net/ftp/ftp_network_layer.h"
|
||||
@@ -68,7 +71,8 @@ AtomBrowserContext::AtomBrowserContext(
|
||||
const std::string& partition, bool in_memory,
|
||||
const base::DictionaryValue& options)
|
||||
: brightray::BrowserContext(partition, in_memory),
|
||||
network_delegate_(new AtomNetworkDelegate) {
|
||||
network_delegate_(new AtomNetworkDelegate),
|
||||
cookie_delegate_(new AtomCookieDelegate) {
|
||||
// Construct user agent string.
|
||||
Browser* browser = Browser::Get();
|
||||
std::string name = RemoveWhitespace(browser->GetName());
|
||||
@@ -104,6 +108,10 @@ net::NetworkDelegate* AtomBrowserContext::CreateNetworkDelegate() {
|
||||
return network_delegate_;
|
||||
}
|
||||
|
||||
net::CookieMonsterDelegate* AtomBrowserContext::CreateCookieDelegate() {
|
||||
return cookie_delegate();
|
||||
}
|
||||
|
||||
std::string AtomBrowserContext::GetUserAgent() {
|
||||
return user_agent_;
|
||||
}
|
||||
@@ -207,6 +215,19 @@ void AtomBrowserContext::RegisterPrefs(PrefRegistrySimple* pref_registry) {
|
||||
pref_registry->RegisterDictionaryPref(prefs::kDevToolsFileSystemPaths);
|
||||
}
|
||||
|
||||
AtomBlobReader* AtomBrowserContext::GetBlobReader() {
|
||||
if (!blob_reader_.get()) {
|
||||
content::ChromeBlobStorageContext* blob_context =
|
||||
content::ChromeBlobStorageContext::GetFor(this);
|
||||
storage::FileSystemContext* file_system_context =
|
||||
content::BrowserContext::GetStoragePartition(
|
||||
this, nullptr)->GetFileSystemContext();
|
||||
blob_reader_.reset(new AtomBlobReader(blob_context,
|
||||
file_system_context));
|
||||
}
|
||||
return blob_reader_.get();
|
||||
}
|
||||
|
||||
// static
|
||||
scoped_refptr<AtomBrowserContext> AtomBrowserContext::From(
|
||||
const std::string& partition, bool in_memory,
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/net/atom_cookie_delegate.h"
|
||||
#include "brightray/browser/browser_context.h"
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomBlobReader;
|
||||
class AtomDownloadManagerDelegate;
|
||||
class AtomNetworkDelegate;
|
||||
class AtomPermissionManager;
|
||||
@@ -30,6 +33,7 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
|
||||
// brightray::URLRequestContextGetter::Delegate:
|
||||
net::NetworkDelegate* CreateNetworkDelegate() override;
|
||||
net::CookieMonsterDelegate* CreateCookieDelegate() override;
|
||||
std::string GetUserAgent() override;
|
||||
std::unique_ptr<net::URLRequestJobFactory> CreateURLRequestJobFactory(
|
||||
content::ProtocolHandlerMap* protocol_handlers) override;
|
||||
@@ -47,7 +51,11 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
// brightray::BrowserContext:
|
||||
void RegisterPrefs(PrefRegistrySimple* pref_registry) override;
|
||||
|
||||
AtomBlobReader* GetBlobReader();
|
||||
AtomNetworkDelegate* network_delegate() const { return network_delegate_; }
|
||||
AtomCookieDelegate* cookie_delegate() const {
|
||||
return cookie_delegate_.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
AtomBrowserContext(const std::string& partition, bool in_memory,
|
||||
@@ -58,11 +66,13 @@ class AtomBrowserContext : public brightray::BrowserContext {
|
||||
std::unique_ptr<AtomDownloadManagerDelegate> download_manager_delegate_;
|
||||
std::unique_ptr<WebViewManager> guest_manager_;
|
||||
std::unique_ptr<AtomPermissionManager> permission_manager_;
|
||||
std::unique_ptr<AtomBlobReader> blob_reader_;
|
||||
std::string user_agent_;
|
||||
bool use_cache_;
|
||||
|
||||
// Managed by brightray::BrowserContext.
|
||||
AtomNetworkDelegate* network_delegate_;
|
||||
scoped_refptr<AtomCookieDelegate> cookie_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
|
||||
if (node_debugger_->IsRunning())
|
||||
env->AssignToContext(v8::Debug::GetDebugContext());
|
||||
|
||||
// Add atom-shell extended APIs.
|
||||
// Add Electron extended APIs.
|
||||
atom_bindings_->BindTo(js_env_->isolate(), env->process_object());
|
||||
|
||||
// Load everything.
|
||||
|
||||
@@ -60,7 +60,7 @@ void AtomDownloadManagerDelegate::CreateDownloadPath(
|
||||
std::string(),
|
||||
suggested_filename,
|
||||
mime_type,
|
||||
std::string());
|
||||
"download");
|
||||
|
||||
if (!base::PathExists(default_download_path))
|
||||
base::CreateDirectory(default_download_path);
|
||||
|
||||
@@ -10,8 +10,17 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/base/escape.h"
|
||||
#include "net/ssl/client_cert_store.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
#if defined(USE_NSS_CERTS)
|
||||
#include "net/ssl/client_cert_store_nss.h"
|
||||
#elif defined(OS_WIN)
|
||||
#include "net/ssl/client_cert_store_win.h"
|
||||
#elif defined(OS_MACOSX)
|
||||
#include "net/ssl/client_cert_store_mac.h"
|
||||
#endif
|
||||
|
||||
using content::BrowserThread;
|
||||
|
||||
namespace atom {
|
||||
@@ -59,7 +68,8 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol(
|
||||
const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
|
||||
bool is_main_frame,
|
||||
ui::PageTransition transition,
|
||||
bool has_user_gesture) {
|
||||
bool has_user_gesture,
|
||||
content::ResourceContext* resource_context) {
|
||||
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(&HandleExternalProtocolInUI,
|
||||
url,
|
||||
@@ -75,4 +85,19 @@ AtomResourceDispatcherHostDelegate::CreateLoginDelegate(
|
||||
return new LoginHandler(auth_info, request);
|
||||
}
|
||||
|
||||
std::unique_ptr<net::ClientCertStore>
|
||||
AtomResourceDispatcherHostDelegate::CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) {
|
||||
#if defined(USE_NSS_CERTS)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(
|
||||
net::ClientCertStoreNSS::PasswordDelegateFactory()));
|
||||
#elif defined(OS_WIN)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
|
||||
#elif defined(OS_MACOSX)
|
||||
return std::unique_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
|
||||
#elif defined(USE_OPENSSL)
|
||||
return std::unique_ptr<net::ClientCertStore>();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -21,10 +21,13 @@ class AtomResourceDispatcherHostDelegate
|
||||
const content::ResourceRequestInfo::WebContentsGetter&,
|
||||
bool is_main_frame,
|
||||
ui::PageTransition transition,
|
||||
bool has_user_gesture) override;
|
||||
bool has_user_gesture,
|
||||
content::ResourceContext* resource_context) override;
|
||||
content::ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
|
||||
net::AuthChallengeInfo* auth_info,
|
||||
net::URLRequest* request) override;
|
||||
std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
|
||||
content::ResourceContext* resource_context) override;
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -27,7 +27,7 @@ bool BridgeTaskRunner::PostDelayedTask(
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||
tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ bool BridgeTaskRunner::PostNonNestableDelayedTask(
|
||||
base::TimeDelta delay) {
|
||||
auto message_loop = base::MessageLoop::current();
|
||||
if (!message_loop) {
|
||||
non_nestable_tasks_.push_back(base::MakeTuple(from_here, task, delay));
|
||||
non_nestable_tasks_.push_back(std::make_tuple(from_here, task, delay));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||
#define ATOM_BROWSER_BRIDGE_TASK_RUNNER_H_
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "base/single_thread_task_runner.h"
|
||||
@@ -33,7 +34,7 @@ class BridgeTaskRunner : public base::SingleThreadTaskRunner {
|
||||
base::TimeDelta delay) override;
|
||||
|
||||
private:
|
||||
using TaskPair = base::Tuple<
|
||||
using TaskPair = std::tuple<
|
||||
tracked_objects::Location, base::Closure, base::TimeDelta>;
|
||||
std::vector<TaskPair> tasks_;
|
||||
std::vector<TaskPair> non_nestable_tasks_;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "base/macros.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/strings/string16.h"
|
||||
#include "base/values.h"
|
||||
#include "native_mate/arguments.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -21,7 +22,6 @@
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class DictionaryValue;
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class Browser : public WindowListObserver {
|
||||
// Overrides the application version.
|
||||
void SetVersion(const std::string& version);
|
||||
|
||||
// Returns the application's name, default is just Atom-Shell.
|
||||
// Returns the application's name, default is just Electron.
|
||||
std::string GetName() const;
|
||||
|
||||
// Overrides the application name.
|
||||
@@ -146,6 +146,9 @@ class Browser : public WindowListObserver {
|
||||
|
||||
// Set docks' icon.
|
||||
void DockSetIcon(const gfx::Image& image);
|
||||
|
||||
void ShowAboutPanel();
|
||||
void SetAboutPanelOptions(const base::DictionaryValue& options);
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -245,6 +248,10 @@ class Browser : public WindowListObserver {
|
||||
base::string16 app_user_model_id_;
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
base::DictionaryValue about_panel_options_;
|
||||
#endif
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Browser);
|
||||
};
|
||||
|
||||
|
||||
@@ -253,4 +253,26 @@ void Browser::DockSetIcon(const gfx::Image& image) {
|
||||
setApplicationIconImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
void Browser::ShowAboutPanel() {
|
||||
NSDictionary* options = DictionaryValueToNSDictionary(about_panel_options_);
|
||||
[[AtomApplication sharedApplication]
|
||||
orderFrontStandardAboutPanelWithOptions:options];
|
||||
}
|
||||
|
||||
void Browser::SetAboutPanelOptions(const base::DictionaryValue& options) {
|
||||
about_panel_options_.Clear();
|
||||
|
||||
// Upper case option keys for orderFrontStandardAboutPanelWithOptions format
|
||||
for (base::DictionaryValue::Iterator iter(options);
|
||||
!iter.IsAtEnd();
|
||||
iter.Advance()) {
|
||||
std::string key = iter.key();
|
||||
std::string value;
|
||||
if (!key.empty() && iter.value().GetAsString(&value)) {
|
||||
key[0] = base::ToUpperASCII(key[0]);
|
||||
about_panel_options_.SetString(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -252,11 +252,11 @@ content::ColorChooser* CommonWebContentsDelegate::OpenColorChooser(
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::RunFileChooser(
|
||||
content::WebContents* guest,
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) {
|
||||
if (!web_dialog_helper_)
|
||||
web_dialog_helper_.reset(new WebDialogHelper(owner_window()));
|
||||
web_dialog_helper_->RunFileChooser(guest, params);
|
||||
web_dialog_helper_->RunFileChooser(render_frame_host, params);
|
||||
}
|
||||
|
||||
void CommonWebContentsDelegate::EnumerateDirectory(content::WebContents* guest,
|
||||
|
||||
@@ -71,7 +71,7 @@ class CommonWebContentsDelegate
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
const std::vector<content::ColorSuggestion>& suggestions) override;
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
void RunFileChooser(content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) override;
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
|
||||
@@ -87,4 +87,8 @@
|
||||
atom::Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
|
||||
- (void)orderFrontStandardAboutPanel:(id)sender {
|
||||
atom::Browser::Get()->ShowAboutPanel();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@interface NSWindow (SierraSDK)
|
||||
@property(class) BOOL allowsAutomaticWindowTabbing;
|
||||
@end
|
||||
|
||||
@implementation AtomApplicationDelegate
|
||||
|
||||
- (void)setApplicationDockMenu:(atom::AtomMenuModel*)model {
|
||||
@@ -21,6 +25,10 @@
|
||||
// Don't add the "Enter Full Screen" menu item automatically.
|
||||
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"NSFullScreenMenuItemEverywhere"];
|
||||
|
||||
// Don't add the "Show Tab Bar" menu item.
|
||||
if ([NSWindow respondsToSelector:@selector(allowsAutomaticWindowTabbing)])
|
||||
NSWindow.allowsAutomaticWindowTabbing = NO;
|
||||
|
||||
atom::Browser::Get()->WillFinishLaunching();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "ipc/ipc_message_macros.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
@@ -390,6 +391,10 @@ void NativeWindow::RequestToClosePage() {
|
||||
if (window_unresposive_closure_.IsCancelled())
|
||||
ScheduleUnresponsiveEvent(5000);
|
||||
|
||||
if (!web_contents())
|
||||
// Already closed by renderer
|
||||
return;
|
||||
|
||||
if (web_contents()->NeedToFireBeforeUnload())
|
||||
web_contents()->DispatchBeforeUnload();
|
||||
else
|
||||
@@ -503,6 +508,11 @@ void NativeWindow::NotifyWindowScrollTouchEnd() {
|
||||
OnWindowScrollTouchEnd());
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowScrollTouchEdge() {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||
OnWindowScrollTouchEdge());
|
||||
}
|
||||
|
||||
void NativeWindow::NotifyWindowSwipe(const std::string& direction) {
|
||||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_,
|
||||
OnWindowSwipe(direction));
|
||||
|
||||
@@ -118,7 +118,8 @@ class NativeWindow : public base::SupportsUserData,
|
||||
virtual bool IsFullScreenable() = 0;
|
||||
virtual void SetClosable(bool closable) = 0;
|
||||
virtual bool IsClosable() = 0;
|
||||
virtual void SetAlwaysOnTop(bool top) = 0;
|
||||
virtual void SetAlwaysOnTop(bool top,
|
||||
const std::string& level = "floating") = 0;
|
||||
virtual bool IsAlwaysOnTop() = 0;
|
||||
virtual void Center() = 0;
|
||||
virtual void SetTitle(const std::string& title) = 0;
|
||||
@@ -207,6 +208,7 @@ class NativeWindow : public base::SupportsUserData,
|
||||
void NotifyWindowMoved();
|
||||
void NotifyWindowScrollTouchBegin();
|
||||
void NotifyWindowScrollTouchEnd();
|
||||
void NotifyWindowScrollTouchEdge();
|
||||
void NotifyWindowSwipe(const std::string& direction);
|
||||
void NotifyWindowEnterFullScreen();
|
||||
void NotifyWindowLeaveFullScreen();
|
||||
|
||||
@@ -64,7 +64,7 @@ class NativeWindowMac : public NativeWindow,
|
||||
bool IsFullScreenable() override;
|
||||
void SetClosable(bool closable) override;
|
||||
bool IsClosable() override;
|
||||
void SetAlwaysOnTop(bool top) override;
|
||||
void SetAlwaysOnTop(bool top, const std::string& level) override;
|
||||
bool IsAlwaysOnTop() override;
|
||||
void Center() override;
|
||||
void SetTitle(const std::string& title) override;
|
||||
@@ -160,9 +160,6 @@ class NativeWindowMac : public NativeWindow,
|
||||
// The "titleBarStyle" option.
|
||||
TitleBarStyle title_bar_style_;
|
||||
|
||||
// Whether user has scrolled the page to edge.
|
||||
bool is_edge_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "content/public/browser/render_widget_host_view.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "skia/ext/skia_utils_mac.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
namespace {
|
||||
@@ -529,8 +530,7 @@ NativeWindowMac::NativeWindowMac(
|
||||
: NativeWindow(web_contents, options, parent),
|
||||
is_kiosk_(false),
|
||||
attention_request_id_(0),
|
||||
title_bar_style_(NORMAL),
|
||||
is_edge_(false) {
|
||||
title_bar_style_(NORMAL) {
|
||||
int width = 800, height = 600;
|
||||
options.Get(options::kWidth, &width);
|
||||
options.Get(options::kHeight, &height);
|
||||
@@ -675,16 +675,14 @@ NativeWindowMac::NativeWindowMac(
|
||||
if (!web_contents)
|
||||
return event;
|
||||
|
||||
if (!began && is_edge_ && (([event phase] == NSEventPhaseMayBegin) ||
|
||||
if (!began && (([event phase] == NSEventPhaseMayBegin) ||
|
||||
([event phase] == NSEventPhaseBegan))) {
|
||||
this->NotifyWindowScrollTouchBegin();
|
||||
began = YES;
|
||||
is_edge_ = false;
|
||||
} else if (began && (([event phase] == NSEventPhaseEnded) ||
|
||||
([event phase] == NSEventPhaseCancelled))) {
|
||||
this->NotifyWindowScrollTouchEnd();
|
||||
began = NO;
|
||||
is_edge_ = false;
|
||||
}
|
||||
return event;
|
||||
}];
|
||||
@@ -742,8 +740,9 @@ bool NativeWindowMac::IsFocused() {
|
||||
|
||||
void NativeWindowMac::Show() {
|
||||
if (is_modal() && parent()) {
|
||||
[parent()->GetNativeWindow() beginSheet:window_
|
||||
completionHandler:^(NSModalResponse) {}];
|
||||
if ([window_ sheetParent] == nil)
|
||||
[parent()->GetNativeWindow() beginSheet:window_
|
||||
completionHandler:^(NSModalResponse) {}];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -945,12 +944,32 @@ bool NativeWindowMac::IsClosable() {
|
||||
return [window_ styleMask] & NSClosableWindowMask;
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetAlwaysOnTop(bool top) {
|
||||
[window_ setLevel:(top ? NSFloatingWindowLevel : NSNormalWindowLevel)];
|
||||
void NativeWindowMac::SetAlwaysOnTop(bool top, const std::string& level) {
|
||||
int windowLevel = NSNormalWindowLevel;
|
||||
if (top) {
|
||||
if (level == "floating") {
|
||||
windowLevel = NSFloatingWindowLevel;
|
||||
} else if (level == "torn-off-menu") {
|
||||
windowLevel = NSTornOffMenuWindowLevel;
|
||||
} else if (level == "modal-panel") {
|
||||
windowLevel = NSModalPanelWindowLevel;
|
||||
} else if (level == "main-menu") {
|
||||
windowLevel = NSMainMenuWindowLevel;
|
||||
} else if (level == "status") {
|
||||
windowLevel = NSStatusWindowLevel;
|
||||
} else if (level == "pop-up-menu") {
|
||||
windowLevel = NSPopUpMenuWindowLevel;
|
||||
} else if (level == "screen-saver") {
|
||||
windowLevel = NSScreenSaverWindowLevel;
|
||||
} else if (level == "dock") {
|
||||
windowLevel = NSDockWindowLevel;
|
||||
}
|
||||
}
|
||||
[window_ setLevel:windowLevel];
|
||||
}
|
||||
|
||||
bool NativeWindowMac::IsAlwaysOnTop() {
|
||||
return [window_ level] == NSFloatingWindowLevel;
|
||||
return [window_ level] != NSNormalWindowLevel;
|
||||
}
|
||||
|
||||
void NativeWindowMac::Center() {
|
||||
@@ -1009,8 +1028,8 @@ bool NativeWindowMac::IsKiosk() {
|
||||
|
||||
void NativeWindowMac::SetBackgroundColor(const std::string& color_name) {
|
||||
SkColor color = ParseHexColor(color_name);
|
||||
base::ScopedCFTypeRef<CGColorRef> cgcolor =
|
||||
skia::CGColorCreateFromSkColor(color);
|
||||
base::ScopedCFTypeRef<CGColorRef> cgcolor(
|
||||
skia::CGColorCreateFromSkColor(color));
|
||||
[[[window_ contentView] layer] setBackgroundColor:cgcolor];
|
||||
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
@@ -1130,7 +1149,7 @@ void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) {
|
||||
case blink::WebInputEvent::GestureScrollBegin:
|
||||
case blink::WebInputEvent::GestureScrollUpdate:
|
||||
case blink::WebInputEvent::GestureScrollEnd:
|
||||
is_edge_ = true;
|
||||
this->NotifyWindowScrollTouchEdge();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -64,6 +64,7 @@ class NativeWindowObserver {
|
||||
virtual void OnWindowMoved() {}
|
||||
virtual void OnWindowScrollTouchBegin() {}
|
||||
virtual void OnWindowScrollTouchEnd() {}
|
||||
virtual void OnWindowScrollTouchEdge() {}
|
||||
virtual void OnWindowSwipe(const std::string& direction) {}
|
||||
virtual void OnWindowEnterFullScreen() {}
|
||||
virtual void OnWindowLeaveFullScreen() {}
|
||||
|
||||
@@ -138,7 +138,7 @@ NativeWindowViews::NativeWindowViews(
|
||||
menu_bar_visible_(false),
|
||||
menu_bar_alt_pressed_(false),
|
||||
#if defined(OS_WIN)
|
||||
enabled_a11y_support_(false),
|
||||
checked_for_a11y_support_(false),
|
||||
thick_frame_(true),
|
||||
#endif
|
||||
keyboard_event_handler_(new views::UnhandledKeyboardEventHandler),
|
||||
@@ -682,7 +682,7 @@ bool NativeWindowViews::IsClosable() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetAlwaysOnTop(bool top) {
|
||||
void NativeWindowViews::SetAlwaysOnTop(bool top, const std::string& level) {
|
||||
window_->SetAlwaysOnTop(top);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "atom/browser/ui/win/message_handler_delegate.h"
|
||||
#include "atom/browser/ui/win/taskbar_host.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#include "ui/base/win/accessibility_misc_utils.h"
|
||||
#include <UIAutomationCoreApi.h>
|
||||
#endif
|
||||
|
||||
namespace views {
|
||||
@@ -84,7 +86,7 @@ class NativeWindowViews : public NativeWindow,
|
||||
bool IsFullScreenable() override;
|
||||
void SetClosable(bool closable) override;
|
||||
bool IsClosable() override;
|
||||
void SetAlwaysOnTop(bool top) override;
|
||||
void SetAlwaysOnTop(bool top, const std::string& level) override;
|
||||
bool IsAlwaysOnTop() override;
|
||||
void Center() override;
|
||||
void SetTitle(const std::string& title) override;
|
||||
@@ -228,8 +230,8 @@ class NativeWindowViews : public NativeWindow,
|
||||
// In charge of running taskbar related APIs.
|
||||
TaskbarHost taskbar_host_;
|
||||
|
||||
// If true we have enabled a11y
|
||||
bool enabled_a11y_support_;
|
||||
// Memoized version of a11y check
|
||||
bool checked_for_a11y_support_;
|
||||
|
||||
// Whether to show the WS_THICKFRAME style.
|
||||
bool thick_frame_;
|
||||
|
||||
@@ -72,6 +72,12 @@ const char* AppCommandToString(int command_id) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsScreenReaderActive() {
|
||||
UINT screenReader = 0;
|
||||
SystemParametersInfo(SPI_GETSCREENREADER, 0, &screenReader, 0);
|
||||
return screenReader && UiaClientsAreListening();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||
@@ -91,16 +97,24 @@ bool NativeWindowViews::PreHandleMSG(
|
||||
// because we still want Chromium to handle returning the actual
|
||||
// accessibility object.
|
||||
case WM_GETOBJECT: {
|
||||
const DWORD obj_id = static_cast<DWORD>(l_param);
|
||||
if (enabled_a11y_support_) return false;
|
||||
if (checked_for_a11y_support_) return false;
|
||||
|
||||
if (obj_id == OBJID_CLIENT) {
|
||||
const auto axState = content::BrowserAccessibilityState::GetInstance();
|
||||
if (axState && !axState->IsAccessibleBrowser()) {
|
||||
axState->OnScreenReaderDetected();
|
||||
enabled_a11y_support_ = true;
|
||||
Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
const DWORD obj_id = static_cast<DWORD>(l_param);
|
||||
|
||||
if (obj_id != OBJID_CLIENT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsScreenReaderActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
checked_for_a11y_support_ = true;
|
||||
|
||||
const auto axState = content::BrowserAccessibilityState::GetInstance();
|
||||
if (axState && !axState->IsAccessibleBrowser()) {
|
||||
axState->OnScreenReaderDetected();
|
||||
Browser::Get()->OnAccessibilitySupportChanged();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -40,10 +40,7 @@ void AtomCertVerifier::SetVerifyProc(const VerifyProc& proc) {
|
||||
}
|
||||
|
||||
int AtomCertVerifier::Verify(
|
||||
net::X509Certificate* cert,
|
||||
const std::string& hostname,
|
||||
const std::string& ocsp_response,
|
||||
int flags,
|
||||
const RequestParams& params,
|
||||
net::CRLSet* crl_set,
|
||||
net::CertVerifyResult* verify_result,
|
||||
const net::CompletionCallback& callback,
|
||||
@@ -53,12 +50,11 @@ int AtomCertVerifier::Verify(
|
||||
|
||||
if (verify_proc_.is_null())
|
||||
return default_cert_verifier_->Verify(
|
||||
cert, hostname, ocsp_response, flags, crl_set, verify_result, callback,
|
||||
out_req, net_log);
|
||||
params, crl_set, verify_result, callback, out_req, net_log);
|
||||
|
||||
BrowserThread::PostTask(
|
||||
BrowserThread::UI, FROM_HERE,
|
||||
base::Bind(verify_proc_, hostname, make_scoped_refptr(cert),
|
||||
base::Bind(verify_proc_, params.hostname(), params.certificate(),
|
||||
base::Bind(OnResult, verify_result, callback)));
|
||||
return net::ERR_IO_PENDING;
|
||||
}
|
||||
|
||||
@@ -26,10 +26,7 @@ class AtomCertVerifier : public net::CertVerifier {
|
||||
|
||||
protected:
|
||||
// net::CertVerifier:
|
||||
int Verify(net::X509Certificate* cert,
|
||||
const std::string& hostname,
|
||||
const std::string& ocsp_response,
|
||||
int flags,
|
||||
int Verify(const RequestParams& params,
|
||||
net::CRLSet* crl_set,
|
||||
net::CertVerifyResult* verify_result,
|
||||
const net::CompletionCallback& callback,
|
||||
|
||||
41
atom/browser/net/atom_cookie_delegate.cc
Normal file
41
atom/browser/net/atom_cookie_delegate.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/browser/net/atom_cookie_delegate.h"
|
||||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
AtomCookieDelegate::AtomCookieDelegate() {
|
||||
}
|
||||
|
||||
AtomCookieDelegate::~AtomCookieDelegate() {
|
||||
}
|
||||
|
||||
void AtomCookieDelegate::AddObserver(Observer* observer) {
|
||||
observers_.AddObserver(observer);
|
||||
}
|
||||
|
||||
void AtomCookieDelegate::RemoveObserver(Observer* observer) {
|
||||
observers_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
void AtomCookieDelegate::NotifyObservers(
|
||||
const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) {
|
||||
FOR_EACH_OBSERVER(Observer,
|
||||
observers_,
|
||||
OnCookieChanged(cookie, removed, cause));
|
||||
}
|
||||
|
||||
void AtomCookieDelegate::OnCookieChanged(
|
||||
const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) {
|
||||
content::BrowserThread::PostTask(
|
||||
content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&AtomCookieDelegate::NotifyObservers,
|
||||
this, cookie, removed, cause));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
48
atom/browser/net/atom_cookie_delegate.h
Normal file
48
atom/browser/net/atom_cookie_delegate.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2016 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_
|
||||
#define ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_
|
||||
|
||||
#include "base/observer_list.h"
|
||||
#include "net/cookies/cookie_monster.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class AtomCookieDelegate : public net::CookieMonsterDelegate {
|
||||
public:
|
||||
AtomCookieDelegate();
|
||||
~AtomCookieDelegate() override;
|
||||
|
||||
class Observer {
|
||||
public:
|
||||
virtual void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
ChangeCause cause) {}
|
||||
protected:
|
||||
virtual ~Observer() {}
|
||||
};
|
||||
|
||||
void AddObserver(Observer* observer);
|
||||
void RemoveObserver(Observer* observer);
|
||||
|
||||
// net::CookieMonsterDelegate:
|
||||
void OnCookieChanged(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
ChangeCause cause) override;
|
||||
|
||||
|
||||
private:
|
||||
base::ObserverList<Observer> observers_;
|
||||
|
||||
void NotifyObservers(const net::CanonicalCookie& cookie,
|
||||
bool removed,
|
||||
ChangeCause cause);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(AtomCookieDelegate);
|
||||
};
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_BROWSER_NET_ATOM_COOKIE_DELEGATE_H_
|
||||
@@ -239,7 +239,7 @@ int AtomNetworkDelegate::OnBeforeURLRequest(
|
||||
return HandleResponseEvent(kOnBeforeRequest, request, callback, new_url);
|
||||
}
|
||||
|
||||
int AtomNetworkDelegate::OnBeforeSendHeaders(
|
||||
int AtomNetworkDelegate::OnBeforeStartTransaction(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) {
|
||||
@@ -254,18 +254,18 @@ int AtomNetworkDelegate::OnBeforeSendHeaders(
|
||||
DevToolsNetworkTransaction::kDevToolsEmulateNetworkConditionsClientId,
|
||||
client_id);
|
||||
if (!ContainsKey(response_listeners_, kOnBeforeSendHeaders))
|
||||
return brightray::NetworkDelegate::OnBeforeSendHeaders(
|
||||
return brightray::NetworkDelegate::OnBeforeStartTransaction(
|
||||
request, callback, headers);
|
||||
|
||||
return HandleResponseEvent(
|
||||
kOnBeforeSendHeaders, request, callback, headers, *headers);
|
||||
}
|
||||
|
||||
void AtomNetworkDelegate::OnSendHeaders(
|
||||
void AtomNetworkDelegate::OnStartTransaction(
|
||||
net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) {
|
||||
if (!ContainsKey(simple_listeners_, kOnSendHeaders)) {
|
||||
brightray::NetworkDelegate::OnSendHeaders(request, headers);
|
||||
brightray::NetworkDelegate::OnStartTransaction(request, headers);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,11 +77,11 @@ class AtomNetworkDelegate : public brightray::NetworkDelegate {
|
||||
int OnBeforeURLRequest(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
GURL* new_url) override;
|
||||
int OnBeforeSendHeaders(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) override;
|
||||
void OnSendHeaders(net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) override;
|
||||
int OnBeforeStartTransaction(net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
net::HttpRequestHeaders* headers) override;
|
||||
void OnStartTransaction(net::URLRequest* request,
|
||||
const net::HttpRequestHeaders& headers) override;
|
||||
int OnHeadersReceived(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
|
||||
@@ -71,8 +71,9 @@ class AtomCopyFrameGenerator {
|
||||
content::BrowserThread::PostDelayedTask(content::BrowserThread::UI,
|
||||
FROM_HERE,
|
||||
base::Bind(&AtomCopyFrameGenerator::InternalGenerateCopyFrame,
|
||||
weak_ptr_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(
|
||||
frame_rate_threshold_ms_ - frame_rate_delta));
|
||||
weak_ptr_factory_.GetWeakPtr()),
|
||||
base::TimeDelta::FromMilliseconds(
|
||||
frame_rate_threshold_ms_ - frame_rate_delta));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -103,9 +104,7 @@ class AtomCopyFrameGenerator {
|
||||
damage_rect));
|
||||
|
||||
request->set_area(gfx::Rect(view_->GetPhysicalBackingSize()));
|
||||
|
||||
view_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput(
|
||||
std::move(request));
|
||||
view_->GetRootLayer()->RequestCopyOfOutput(std::move(request));
|
||||
}
|
||||
|
||||
void CopyFromCompositingSurfaceHasResult(
|
||||
@@ -302,10 +301,9 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient {
|
||||
AtomBeginFrameTimer(int frame_rate_threshold_ms,
|
||||
const base::Closure& callback)
|
||||
: callback_(callback) {
|
||||
time_source_ = cc::DelayBasedTimeSource::Create(
|
||||
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms),
|
||||
time_source_.reset(new cc::DelayBasedTimeSource(
|
||||
content::BrowserThread::GetMessageLoopProxyForThread(
|
||||
content::BrowserThread::UI).get());
|
||||
content::BrowserThread::UI).get()));
|
||||
time_source_->SetClient(this);
|
||||
}
|
||||
|
||||
@@ -351,12 +349,17 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
is_showing_(!render_widget_host_->is_hidden()),
|
||||
size_(native_window->GetSize()),
|
||||
painting_(true),
|
||||
root_layer_(new ui::Layer(ui::LAYER_SOLID_COLOR)),
|
||||
#if !defined(OS_MACOSX)
|
||||
delegated_frame_host_(new content::DelegatedFrameHost(this)),
|
||||
#endif
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(render_widget_host_);
|
||||
render_widget_host_->SetView(this);
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
CreatePlatformWidget();
|
||||
#else
|
||||
@@ -364,17 +367,29 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
new ui::Compositor(content::GetContextFactory(),
|
||||
base::ThreadTaskRunnerHandle::Get()));
|
||||
compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget());
|
||||
#endif
|
||||
compositor_->SetDelegate(this);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
#endif
|
||||
GetCompositor()->SetDelegate(this);
|
||||
|
||||
native_window_->AddObserver(this);
|
||||
|
||||
ResizeRootLayer();
|
||||
}
|
||||
|
||||
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
||||
if (native_window_)
|
||||
native_window_->RemoveObserver(this);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
if (is_showing_)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
#else
|
||||
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
||||
// necessary to remove all connections to its old ui::Compositor.
|
||||
if (is_showing_)
|
||||
delegated_frame_host_->WasHidden();
|
||||
delegated_frame_host_->ResetCompositor();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
DestroyPlatformWidget();
|
||||
@@ -429,11 +444,10 @@ content::RenderWidgetHost* OffScreenRenderWidgetHostView::GetRenderWidgetHost()
|
||||
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
||||
size_ = size;
|
||||
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ConvertSizeToPixel(scale_factor_, size);
|
||||
|
||||
root_layer_->SetBounds(gfx::Rect(size));
|
||||
compositor_->SetScaleAndSize(scale_factor_, size_in_pixels);
|
||||
ResizeRootLayer();
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasResized();
|
||||
GetDelegatedFrameHost()->WasResized();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetBounds(const gfx::Rect& new_bounds) {
|
||||
@@ -464,7 +478,7 @@ bool OffScreenRenderWidgetHostView::HasFocus() const {
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::IsSurfaceAvailableForCopy() const {
|
||||
return delegated_frame_host_->CanCopyToBitmap();
|
||||
return GetDelegatedFrameHost()->CanCopyToBitmap();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Show() {
|
||||
@@ -472,10 +486,16 @@ void OffScreenRenderWidgetHostView::Show() {
|
||||
return;
|
||||
|
||||
is_showing_ = true;
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasShown(ui::LatencyInfo());
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(false);
|
||||
#else
|
||||
delegated_frame_host_->SetCompositor(compositor_.get());
|
||||
delegated_frame_host_->WasShown(ui::LatencyInfo());
|
||||
#endif
|
||||
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasShown(ui::LatencyInfo());
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Hide() {
|
||||
@@ -484,8 +504,14 @@ void OffScreenRenderWidgetHostView::Hide() {
|
||||
|
||||
if (render_widget_host_)
|
||||
render_widget_host_->WasHidden();
|
||||
delegated_frame_host_->WasHidden();
|
||||
delegated_frame_host_->ResetCompositor();
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetRenderWidgetHostIsHidden(true);
|
||||
#else
|
||||
GetDelegatedFrameHost()->WasHidden();
|
||||
GetDelegatedFrameHost()->ResetCompositor();
|
||||
#endif
|
||||
|
||||
is_showing_ = false;
|
||||
}
|
||||
|
||||
@@ -522,52 +548,63 @@ bool OffScreenRenderWidgetHostView::LockMouse() {
|
||||
void OffScreenRenderWidgetHostView::UnlockMouse() {
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::GetScreenColorProfile(std::vector<char>*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnSwapCompositorFrame(
|
||||
uint32_t output_surface_id,
|
||||
std::unique_ptr<cc::CompositorFrame> frame) {
|
||||
cc::CompositorFrame frame) {
|
||||
TRACE_EVENT0("electron",
|
||||
"OffScreenRenderWidgetHostView::OnSwapCompositorFrame");
|
||||
|
||||
if (frame->metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame->metadata.root_scroll_offset;
|
||||
if (frame.metadata.root_scroll_offset != last_scroll_offset_) {
|
||||
last_scroll_offset_ = frame.metadata.root_scroll_offset;
|
||||
}
|
||||
|
||||
if (frame->delegated_frame_data) {
|
||||
if (frame.delegated_frame_data) {
|
||||
if (software_output_device_) {
|
||||
if (!begin_frame_timer_.get()) {
|
||||
software_output_device_->SetActive(painting_);
|
||||
}
|
||||
|
||||
// The compositor will draw directly to the SoftwareOutputDevice which
|
||||
// then calls OnPaint.
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SwapCompositorFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
#else
|
||||
delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
#endif
|
||||
} else {
|
||||
if (!copy_frame_generator_.get()) {
|
||||
copy_frame_generator_.reset(
|
||||
new AtomCopyFrameGenerator(frame_rate_threshold_ms_, this));
|
||||
}
|
||||
|
||||
// Determine the damage rectangle for the current frame. This is the same
|
||||
// calculation that SwapDelegatedFrame uses.
|
||||
cc::RenderPass* root_pass =
|
||||
frame->delegated_frame_data->render_pass_list.back().get();
|
||||
frame.delegated_frame_data->render_pass_list.back().get();
|
||||
gfx::Size frame_size = root_pass->output_rect.size();
|
||||
gfx::Rect damage_rect =
|
||||
gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect));
|
||||
damage_rect.Intersect(gfx::Rect(frame_size));
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SwapCompositorFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
#else
|
||||
delegated_frame_host_->SwapDelegatedFrame(output_surface_id,
|
||||
std::move(frame));
|
||||
#endif
|
||||
|
||||
if (painting_)
|
||||
copy_frame_generator_->GenerateCopyFrame(true, damage_rect);
|
||||
// Request a copy of the last compositor frame which will eventually call
|
||||
// OnPaint asynchronously.
|
||||
copy_frame_generator_->GenerateCopyFrame(true, damage_rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ClearCompositorFrame() {
|
||||
delegated_frame_host_->ClearDelegatedFrame();
|
||||
GetDelegatedFrameHost()->ClearDelegatedFrame();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::InitAsPopup(
|
||||
@@ -612,7 +649,7 @@ void OffScreenRenderWidgetHostView::CopyFromCompositingSurface(
|
||||
const gfx::Size& dst_size,
|
||||
const content::ReadbackRequestCallback& callback,
|
||||
const SkColorType preferred_color_type) {
|
||||
delegated_frame_host_->CopyFromCompositingSurface(
|
||||
GetDelegatedFrameHost()->CopyFromCompositingSurface(
|
||||
src_subrect, dst_size, callback, preferred_color_type);
|
||||
}
|
||||
|
||||
@@ -620,21 +657,21 @@ void OffScreenRenderWidgetHostView::CopyFromCompositingSurfaceToVideoFrame(
|
||||
const gfx::Rect& src_subrect,
|
||||
const scoped_refptr<media::VideoFrame>& target,
|
||||
const base::Callback<void(const gfx::Rect&, bool)>& callback) {
|
||||
delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
|
||||
GetDelegatedFrameHost()->CopyFromCompositingSurfaceToVideoFrame(
|
||||
src_subrect, target, callback);
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::CanCopyToVideoFrame() const {
|
||||
return delegated_frame_host_->CanCopyToVideoFrame();
|
||||
return GetDelegatedFrameHost()->CanCopyToVideoFrame();
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::BeginFrameSubscription(
|
||||
std::unique_ptr<content::RenderWidgetHostViewFrameSubscriber> subscriber) {
|
||||
delegated_frame_host_->BeginFrameSubscription(std::move(subscriber));
|
||||
GetDelegatedFrameHost()->BeginFrameSubscription(std::move(subscriber));
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::EndFrameSubscription() {
|
||||
delegated_frame_host_->EndFrameSubscription();
|
||||
GetDelegatedFrameHost()->EndFrameSubscription();
|
||||
}
|
||||
|
||||
bool OffScreenRenderWidgetHostView::HasAcceleratedSurface(const gfx::Size &) {
|
||||
@@ -749,7 +786,7 @@ void OffScreenRenderWidgetHostView::SetBeginFrameSource(
|
||||
std::unique_ptr<cc::SoftwareOutputDevice>
|
||||
OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice(
|
||||
ui::Compositor* compositor) {
|
||||
DCHECK_EQ(compositor_.get(), compositor);
|
||||
DCHECK_EQ(GetCompositor(), compositor);
|
||||
DCHECK(!copy_frame_generator_);
|
||||
DCHECK(!software_output_device_);
|
||||
|
||||
@@ -763,7 +800,11 @@ std::unique_ptr<cc::SoftwareOutputDevice>
|
||||
bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
||||
if (transparent_) {
|
||||
SetBackgroundColor(SkColor());
|
||||
#if defined(OS_MACOSX)
|
||||
browser_compositor_->SetHasTransparentBackground(true);
|
||||
#else
|
||||
compositor_->SetHostHasTransparentBackground(true);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -816,13 +857,28 @@ int OffScreenRenderWidgetHostView::GetFrameRate() const {
|
||||
return frame_rate_;
|
||||
}
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||
return compositor_.get();
|
||||
}
|
||||
|
||||
ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||
return root_layer_.get();
|
||||
}
|
||||
|
||||
content::DelegatedFrameHost*
|
||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||
return delegated_frame_host_.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
if (!force && frame_rate_threshold_ms_ != 0)
|
||||
return;
|
||||
|
||||
frame_rate_threshold_ms_ = 1000 / frame_rate_;
|
||||
|
||||
compositor_->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval(
|
||||
base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_));
|
||||
|
||||
if (copy_frame_generator_.get()) {
|
||||
@@ -840,6 +896,16 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::Invalidate() {
|
||||
const gfx::Rect& bounds_in_pixels = GetViewBounds();
|
||||
|
||||
if (software_output_device_) {
|
||||
software_output_device_->OnPaint(bounds_in_pixels);
|
||||
} else if (copy_frame_generator_.get()) {
|
||||
copy_frame_generator_->GenerateCopyFrame(true, bounds_in_pixels);
|
||||
}
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::ResizeRootLayer() {
|
||||
SetupFrameRate(false);
|
||||
|
||||
@@ -848,14 +914,25 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer() {
|
||||
|
||||
gfx::Size size = GetViewBounds().size();
|
||||
|
||||
if (!scaleFactorDidChange && size == root_layer_->bounds().size())
|
||||
if (!scaleFactorDidChange && size == GetRootLayer()->bounds().size())
|
||||
return;
|
||||
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ConvertSizeToPixel(scale_factor_, size);
|
||||
|
||||
root_layer_->SetBounds(gfx::Rect(size));
|
||||
compositor_->SetScaleAndSize(scale_factor_, size_in_pixels);
|
||||
GetRootLayer()->SetBounds(gfx::Rect(size));
|
||||
GetCompositor()->SetScaleAndSize(scale_factor_, size_in_pixels);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnWindowResize() {
|
||||
// In offscreen mode call RenderWidgetHostView's SetSize explicitly
|
||||
auto size = native_window_->GetSize();
|
||||
SetSize(size);
|
||||
}
|
||||
|
||||
void OffScreenRenderWidgetHostView::OnWindowClosed() {
|
||||
native_window_->RemoveObserver(this);
|
||||
native_window_ = nullptr;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#endif
|
||||
|
||||
#include "atom/browser/native_window.h"
|
||||
#include "atom/browser/native_window_observer.h"
|
||||
#include "atom/browser/osr/osr_output_device.h"
|
||||
#include "base/process/kill.h"
|
||||
#include "base/threading/thread.h"
|
||||
@@ -36,7 +37,6 @@
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "content/browser/renderer_host/browser_compositor_view_mac.h"
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
@@ -54,13 +54,15 @@ namespace atom {
|
||||
class AtomCopyFrameGenerator;
|
||||
class AtomBeginFrameTimer;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
class MacHelper;
|
||||
#endif
|
||||
|
||||
class OffScreenRenderWidgetHostView
|
||||
: public content::RenderWidgetHostViewBase,
|
||||
#if defined(OS_MACOSX)
|
||||
public ui::AcceleratedWidgetMacNSView,
|
||||
#endif
|
||||
public ui::CompositorDelegate,
|
||||
public content::DelegatedFrameHostClient {
|
||||
public content::DelegatedFrameHostClient,
|
||||
public NativeWindowObserver {
|
||||
public:
|
||||
OffScreenRenderWidgetHostView(bool transparent,
|
||||
const OnPaintCallback& callback,
|
||||
@@ -90,7 +92,6 @@ class OffScreenRenderWidgetHostView
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
bool LockMouse(void) override;
|
||||
void UnlockMouse(void) override;
|
||||
bool GetScreenColorProfile(std::vector<char>*) override;
|
||||
#if defined(OS_MACOSX)
|
||||
ui::AcceleratedWidgetMac* GetAcceleratedWidgetMac() const override;
|
||||
void SetActive(bool active) override;
|
||||
@@ -102,7 +103,7 @@ class OffScreenRenderWidgetHostView
|
||||
#endif // defined(OS_MACOSX)
|
||||
|
||||
// content::RenderWidgetHostViewBase:
|
||||
void OnSwapCompositorFrame(uint32_t, std::unique_ptr<cc::CompositorFrame>)
|
||||
void OnSwapCompositorFrame(uint32_t, cc::CompositorFrame)
|
||||
override;
|
||||
void ClearCompositorFrame(void) override;
|
||||
void InitAsPopup(content::RenderWidgetHostView *rwhv, const gfx::Rect& rect)
|
||||
@@ -173,13 +174,9 @@ class OffScreenRenderWidgetHostView
|
||||
bool IsAutoResizeEnabled() const;
|
||||
void OnSetNeedsBeginFrames(bool enabled);
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// ui::AcceleratedWidgetMacNSView:
|
||||
NSView* AcceleratedWidgetGetNSView() const override;
|
||||
void AcceleratedWidgetGetVSyncParameters(
|
||||
base::TimeTicks* timebase, base::TimeDelta* interval) const override;
|
||||
void AcceleratedWidgetSwapCompleted() override;
|
||||
#endif // defined(OS_MACOSX)
|
||||
// NativeWindowObserver:
|
||||
void OnWindowResize() override;
|
||||
void OnWindowClosed() override;
|
||||
|
||||
void OnBeginFrameTimerTick();
|
||||
void SendBeginFrame(base::TimeTicks frame_time,
|
||||
@@ -198,9 +195,15 @@ class OffScreenRenderWidgetHostView
|
||||
void SetFrameRate(int frame_rate);
|
||||
int GetFrameRate() const;
|
||||
|
||||
ui::Compositor* compositor() const { return compositor_.get(); }
|
||||
ui::Compositor* GetCompositor() const;
|
||||
ui::Layer* GetRootLayer() const;
|
||||
content::DelegatedFrameHost* GetDelegatedFrameHost() const;
|
||||
|
||||
void Invalidate();
|
||||
|
||||
content::RenderWidgetHostImpl* render_widget_host() const
|
||||
{ return render_widget_host_; }
|
||||
NativeWindow* window() const { return native_window_; }
|
||||
|
||||
private:
|
||||
void SetupFrameRate(bool force);
|
||||
@@ -233,10 +236,13 @@ class OffScreenRenderWidgetHostView
|
||||
std::unique_ptr<AtomBeginFrameTimer> begin_frame_timer_;
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
NSWindow* window_;
|
||||
CALayer* background_layer_;
|
||||
std::unique_ptr<content::BrowserCompositorMac> browser_compositor_;
|
||||
|
||||
// Can not be managed by smart pointer because its header can not be included
|
||||
// in the file that has the destructor.
|
||||
MacHelper* mac_helper_;
|
||||
|
||||
// Selected text on the renderer.
|
||||
std::string selected_text_;
|
||||
#endif
|
||||
|
||||
@@ -7,48 +7,115 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "content/common/view_messages.h"
|
||||
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
class MacHelper :
|
||||
public content::BrowserCompositorMacClient,
|
||||
public ui::AcceleratedWidgetMacNSView {
|
||||
public:
|
||||
explicit MacHelper(OffScreenRenderWidgetHostView* view) : view_(view) {}
|
||||
virtual ~MacHelper() {}
|
||||
|
||||
// content::BrowserCompositorMacClient:
|
||||
NSView* BrowserCompositorMacGetNSView() const override {
|
||||
// Intentionally return nil so that
|
||||
// BrowserCompositorMac::DelegatedFrameHostDesiredSizeInDIP uses the layer
|
||||
// size instead of the NSView size.
|
||||
return nil;
|
||||
}
|
||||
|
||||
SkColor BrowserCompositorMacGetGutterColor(SkColor color) const override {
|
||||
// When making an element on the page fullscreen the element's background
|
||||
// may not match the page's, so use black as the gutter color to avoid
|
||||
// flashes of brighter colors during the transition.
|
||||
if (view_->render_widget_host()->delegate() &&
|
||||
view_->render_widget_host()->delegate()->IsFullscreenForCurrentTab()) {
|
||||
return SK_ColorBLACK;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendCompositorSwapAck(
|
||||
int output_surface_id,
|
||||
const cc::CompositorFrameAck& ack) override {
|
||||
view_->render_widget_host()->Send(new ViewMsg_SwapCompositorFrameAck(
|
||||
view_->render_widget_host()->GetRoutingID(), output_surface_id, ack));
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendReclaimCompositorResources(
|
||||
int output_surface_id,
|
||||
const cc::CompositorFrameAck& ack) override {
|
||||
view_->render_widget_host()->Send(new ViewMsg_ReclaimCompositorResources(
|
||||
view_->render_widget_host()->GetRoutingID(), output_surface_id, ack));
|
||||
}
|
||||
|
||||
void BrowserCompositorMacOnLostCompositorResources() override {
|
||||
view_->render_widget_host()->ScheduleComposite();
|
||||
}
|
||||
|
||||
void BrowserCompositorMacUpdateVSyncParameters(
|
||||
const base::TimeTicks& timebase,
|
||||
const base::TimeDelta& interval) override {
|
||||
view_->render_widget_host()->UpdateVSyncParameters(timebase, interval);
|
||||
}
|
||||
|
||||
void BrowserCompositorMacSendBeginFrame(
|
||||
const cc::BeginFrameArgs& args) override {
|
||||
view_->render_widget_host()->Send(
|
||||
new ViewMsg_BeginFrame(view_->render_widget_host()->GetRoutingID(),
|
||||
args));
|
||||
}
|
||||
// ui::AcceleratedWidgetMacNSView:
|
||||
NSView* AcceleratedWidgetGetNSView() const override {
|
||||
return [view_->window()->GetNativeWindow() contentView];
|
||||
}
|
||||
|
||||
void AcceleratedWidgetGetVSyncParameters(
|
||||
base::TimeTicks* timebase, base::TimeDelta* interval) const override {
|
||||
*timebase = base::TimeTicks();
|
||||
*interval = base::TimeDelta();
|
||||
}
|
||||
|
||||
void AcceleratedWidgetSwapCompleted() override {
|
||||
}
|
||||
|
||||
private:
|
||||
OffScreenRenderWidgetHostView* view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(MacHelper);
|
||||
};
|
||||
|
||||
ui::AcceleratedWidgetMac*
|
||||
atom::OffScreenRenderWidgetHostView::GetAcceleratedWidgetMac() const {
|
||||
OffScreenRenderWidgetHostView::GetAcceleratedWidgetMac() const {
|
||||
if (browser_compositor_)
|
||||
return browser_compositor_->accelerated_widget_mac();
|
||||
return browser_compositor_->GetAcceleratedWidgetMac();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NSView* atom::OffScreenRenderWidgetHostView::AcceleratedWidgetGetNSView() const {
|
||||
return [native_window_->GetNativeWindow() contentView];
|
||||
void OffScreenRenderWidgetHostView::SetActive(bool active) {
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::AcceleratedWidgetGetVSyncParameters(
|
||||
base::TimeTicks* timebase, base::TimeDelta* interval) const {
|
||||
*timebase = base::TimeTicks();
|
||||
*interval = base::TimeDelta();
|
||||
void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::AcceleratedWidgetSwapCompleted() {
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::SetActive(bool active) {
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {
|
||||
}
|
||||
|
||||
bool atom::OffScreenRenderWidgetHostView::SupportsSpeech() const {
|
||||
bool OffScreenRenderWidgetHostView::SupportsSpeech() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::SpeakSelection() {
|
||||
void OffScreenRenderWidgetHostView::SpeakSelection() {
|
||||
}
|
||||
|
||||
bool atom::OffScreenRenderWidgetHostView::IsSpeaking() const {
|
||||
bool OffScreenRenderWidgetHostView::IsSpeaking() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::StopSpeaking() {
|
||||
void OffScreenRenderWidgetHostView::StopSpeaking() {
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::SelectionChanged(
|
||||
void OffScreenRenderWidgetHostView::SelectionChanged(
|
||||
const base::string16& text,
|
||||
size_t offset,
|
||||
const gfx::Range& range) {
|
||||
@@ -69,24 +136,28 @@ void atom::OffScreenRenderWidgetHostView::SelectionChanged(
|
||||
RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::CreatePlatformWidget() {
|
||||
browser_compositor_ = content::BrowserCompositorMac::Create();
|
||||
|
||||
compositor_.reset(browser_compositor_->compositor());
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
browser_compositor_->accelerated_widget_mac()->SetNSView(this);
|
||||
browser_compositor_->compositor()->SetVisible(true);
|
||||
|
||||
compositor_->SetLocksWillTimeOut(true);
|
||||
browser_compositor_->Unsuspend();
|
||||
void OffScreenRenderWidgetHostView::CreatePlatformWidget() {
|
||||
mac_helper_ = new MacHelper(this);
|
||||
browser_compositor_.reset(new content::BrowserCompositorMac(
|
||||
mac_helper_, mac_helper_, render_widget_host_->is_hidden(), true));
|
||||
}
|
||||
|
||||
void atom::OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
|
||||
ui::Compositor* compositor = compositor_.release();
|
||||
ALLOW_UNUSED_LOCAL(compositor);
|
||||
|
||||
browser_compositor_->accelerated_widget_mac()->ResetNSView();
|
||||
browser_compositor_->compositor()->SetVisible(false);
|
||||
browser_compositor_->compositor()->SetScaleAndSize(1.0, gfx::Size(0, 0));
|
||||
browser_compositor_->compositor()->SetRootLayer(NULL);
|
||||
void OffScreenRenderWidgetHostView::DestroyPlatformWidget() {
|
||||
browser_compositor_.reset();
|
||||
delete mac_helper_;
|
||||
}
|
||||
|
||||
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() const {
|
||||
return browser_compositor_->GetCompositor();
|
||||
}
|
||||
|
||||
ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
|
||||
return browser_compositor_->GetRootLayer();
|
||||
}
|
||||
|
||||
content::DelegatedFrameHost*
|
||||
OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
|
||||
return browser_compositor_->GetDelegatedFrameHost();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "atom/browser/osr/osr_web_contents_view.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface OffScreenView : NSView
|
||||
@end
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>electron.icns</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.3.6</string>
|
||||
<string>1.4.4</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.3.6</string>
|
||||
<string>1.4.4</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -56,8 +56,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,3,6,0
|
||||
PRODUCTVERSION 1,3,6,0
|
||||
FILEVERSION 1,4,4,0
|
||||
PRODUCTVERSION 1,4,4,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -74,12 +74,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "GitHub, Inc."
|
||||
VALUE "FileDescription", "Electron"
|
||||
VALUE "FileVersion", "1.3.6"
|
||||
VALUE "FileVersion", "1.4.4"
|
||||
VALUE "InternalName", "electron.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved."
|
||||
VALUE "OriginalFilename", "electron.exe"
|
||||
VALUE "ProductName", "Electron"
|
||||
VALUE "ProductVersion", "1.3.6"
|
||||
VALUE "ProductVersion", "1.4.4"
|
||||
VALUE "SquirrelAwareVersion", "1"
|
||||
END
|
||||
END
|
||||
|
||||
@@ -63,7 +63,9 @@ void MenuBar::SetMenu(AtomMenuModel* model) {
|
||||
RemoveAllChildViews(true);
|
||||
|
||||
for (int i = 0; i < model->GetItemCount(); ++i) {
|
||||
SubmenuButton* button = new SubmenuButton(this, model->GetLabelAt(i), this);
|
||||
SubmenuButton* button = new SubmenuButton(model->GetLabelAt(i),
|
||||
this,
|
||||
background_color_);
|
||||
button->set_tag(i);
|
||||
|
||||
#if defined(USE_X11)
|
||||
@@ -131,9 +133,6 @@ const char* MenuBar::GetClassName() const {
|
||||
return kViewClassName;
|
||||
}
|
||||
|
||||
void MenuBar::ButtonPressed(views::Button* sender, const ui::Event& event) {
|
||||
}
|
||||
|
||||
void MenuBar::OnMenuButtonClicked(views::MenuButton* source,
|
||||
const gfx::Point& point,
|
||||
const ui::Event* event) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#define ATOM_BROWSER_UI_VIEWS_MENU_BAR_H_
|
||||
|
||||
#include "atom/browser/ui/atom_menu_model.h"
|
||||
#include "ui/views/controls/button/button.h"
|
||||
#include "ui/views/controls/button/menu_button_listener.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
@@ -19,7 +18,6 @@ namespace atom {
|
||||
class MenuDelegate;
|
||||
|
||||
class MenuBar : public views::View,
|
||||
public views::ButtonListener,
|
||||
public views::MenuButtonListener {
|
||||
public:
|
||||
MenuBar();
|
||||
@@ -50,9 +48,6 @@ class MenuBar : public views::View,
|
||||
// views::View:
|
||||
const char* GetClassName() const override;
|
||||
|
||||
// views::ButtonListener:
|
||||
void ButtonPressed(views::Button* sender, const ui::Event& event) override;
|
||||
|
||||
// views::MenuButtonListener:
|
||||
void OnMenuButtonClicked(views::MenuButton* source,
|
||||
const gfx::Point& point,
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/color_utils.h"
|
||||
#include "ui/gfx/text_utils.h"
|
||||
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
|
||||
#include "ui/views/animation/ink_drop_host_view.h"
|
||||
#include "ui/views/controls/button/label_button_border.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -23,9 +26,9 @@ base::string16 FilterAccelerator(const base::string16& label) {
|
||||
|
||||
} // namespace
|
||||
|
||||
SubmenuButton::SubmenuButton(views::ButtonListener* listener,
|
||||
const base::string16& title,
|
||||
views::MenuButtonListener* menu_button_listener)
|
||||
SubmenuButton::SubmenuButton(const base::string16& title,
|
||||
views::MenuButtonListener* menu_button_listener,
|
||||
const SkColor& background_color)
|
||||
: views::MenuButton(FilterAccelerator(title),
|
||||
menu_button_listener, false),
|
||||
accelerator_(0),
|
||||
@@ -34,7 +37,8 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener,
|
||||
underline_end_(-1),
|
||||
text_width_(0),
|
||||
text_height_(0),
|
||||
underline_color_(SK_ColorBLACK) {
|
||||
underline_color_(SK_ColorBLACK),
|
||||
background_color_(background_color) {
|
||||
#if defined(OS_LINUX)
|
||||
// Dont' use native style border.
|
||||
SetBorder(std::move(CreateDefaultBorder()));
|
||||
@@ -44,11 +48,45 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener,
|
||||
&underline_end_))
|
||||
gfx::Canvas::SizeStringInt(GetText(), GetFontList(), &text_width_,
|
||||
&text_height_, 0, 0);
|
||||
|
||||
SetHasInkDrop(true);
|
||||
set_ink_drop_base_color(
|
||||
color_utils::BlendTowardOppositeLuma(background_color_, 0x61));
|
||||
|
||||
set_request_focus_on_press(true);
|
||||
SetFocusForPlatform();
|
||||
SetFocusPainter(nullptr);
|
||||
}
|
||||
|
||||
SubmenuButton::~SubmenuButton() {
|
||||
}
|
||||
|
||||
std::unique_ptr<views::InkDropRipple> SubmenuButton::CreateInkDropRipple()
|
||||
const {
|
||||
return base::MakeUnique<views::FloodFillInkDropRipple>(
|
||||
GetLocalBounds(),
|
||||
GetInkDropCenterBasedOnLastEvent(),
|
||||
GetInkDropBaseColor(),
|
||||
ink_drop_visible_opacity());
|
||||
}
|
||||
|
||||
std::unique_ptr<views::InkDropHighlight>
|
||||
SubmenuButton::CreateInkDropHighlight() const {
|
||||
if (!ShouldShowInkDropHighlight())
|
||||
return nullptr;
|
||||
|
||||
gfx::Size size = GetLocalBounds().size();
|
||||
return base::MakeUnique<views::InkDropHighlight>(
|
||||
size,
|
||||
kInkDropSmallCornerRadius,
|
||||
gfx::RectF(gfx::SizeF(size)).CenterPoint(),
|
||||
GetInkDropBaseColor());
|
||||
}
|
||||
|
||||
bool SubmenuButton::ShouldShowInkDropForFocus() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubmenuButton::SetAcceleratorVisibility(bool visible) {
|
||||
if (visible == show_underline_)
|
||||
return;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef ATOM_BROWSER_UI_VIEWS_SUBMENU_BUTTON_H_
|
||||
#define ATOM_BROWSER_UI_VIEWS_SUBMENU_BUTTON_H_
|
||||
|
||||
#include "ui/views/animation/ink_drop_highlight.h"
|
||||
#include "ui/views/controls/button/menu_button.h"
|
||||
|
||||
namespace atom {
|
||||
@@ -12,9 +13,9 @@ namespace atom {
|
||||
// Special button that used by menu bar to show submenus.
|
||||
class SubmenuButton : public views::MenuButton {
|
||||
public:
|
||||
SubmenuButton(views::ButtonListener* listener,
|
||||
const base::string16& title,
|
||||
views::MenuButtonListener* menu_button_listener);
|
||||
SubmenuButton(const base::string16& title,
|
||||
views::MenuButtonListener* menu_button_listener,
|
||||
const SkColor& background_color);
|
||||
virtual ~SubmenuButton();
|
||||
|
||||
void SetAcceleratorVisibility(bool visible);
|
||||
@@ -28,6 +29,12 @@ class SubmenuButton : public views::MenuButton {
|
||||
// views::MenuButton:
|
||||
void OnPaint(gfx::Canvas* canvas) override;
|
||||
|
||||
// views::InkDropHostView:
|
||||
std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
|
||||
std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
|
||||
const override;
|
||||
bool ShouldShowInkDropForFocus() const override;
|
||||
|
||||
private:
|
||||
bool GetUnderlinePosition(const base::string16& text,
|
||||
base::char16* accelerator,
|
||||
@@ -44,6 +51,7 @@ class SubmenuButton : public views::MenuButton {
|
||||
int text_width_;
|
||||
int text_height_;
|
||||
SkColor underline_color_;
|
||||
SkColor background_color_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SubmenuButton);
|
||||
};
|
||||
|
||||
@@ -97,6 +97,12 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
||||
command_line->AppendSwitchASCII(switches::kNodeIntegration,
|
||||
node_integration ? "true" : "false");
|
||||
|
||||
// If the `sandbox` option was passed to the BrowserWindow's webPreferences,
|
||||
// pass `--enable-sandbox` to the renderer so it won't have any node.js
|
||||
// integration.
|
||||
if (IsSandboxed(web_contents))
|
||||
command_line->AppendSwitch(switches::kEnableSandbox);
|
||||
|
||||
// The preload script.
|
||||
base::FilePath::StringType preload;
|
||||
if (web_preferences.GetString(options::kPreloadScript, &preload)) {
|
||||
@@ -194,6 +200,21 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
|
||||
command_line->AppendSwitch(cc::switches::kEnableBeginFrameScheduling);
|
||||
}
|
||||
|
||||
bool WebContentsPreferences::IsSandboxed(content::WebContents* web_contents) {
|
||||
WebContentsPreferences* self;
|
||||
if (!web_contents)
|
||||
return false;
|
||||
|
||||
self = FromWebContents(web_contents);
|
||||
if (!self)
|
||||
return false;
|
||||
|
||||
base::DictionaryValue& web_preferences = self->web_preferences_;
|
||||
bool sandboxed = false;
|
||||
web_preferences.GetBoolean("sandbox", &sandboxed);
|
||||
return sandboxed;
|
||||
}
|
||||
|
||||
// static
|
||||
void WebContentsPreferences::OverrideWebkitPrefs(
|
||||
content::WebContents* web_contents, content::WebPreferences* prefs) {
|
||||
|
||||
@@ -36,6 +36,8 @@ class WebContentsPreferences
|
||||
static void AppendExtraCommandLineSwitches(
|
||||
content::WebContents* web_contents, base::CommandLine* command_line);
|
||||
|
||||
static bool IsSandboxed(content::WebContents* web_contents);
|
||||
|
||||
// Modify the WebPreferences according to |web_contents|'s preferences.
|
||||
static void OverrideWebkitPrefs(
|
||||
content::WebContents* web_contents, content::WebPreferences* prefs);
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "chrome/common/pref_names.h"
|
||||
#include "components/prefs/pref_service.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/web_contents.h"
|
||||
#include "content/public/common/file_chooser_file_info.h"
|
||||
#include "content/public/common/file_chooser_params.h"
|
||||
#include "net/base/mime_util.h"
|
||||
#include "ui/shell_dialogs/selected_file_info.h"
|
||||
|
||||
@@ -75,8 +77,9 @@ WebDialogHelper::~WebDialogHelper() {
|
||||
}
|
||||
|
||||
|
||||
void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
|
||||
const content::FileChooserParams& params) {
|
||||
void WebDialogHelper::RunFileChooser(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params) {
|
||||
std::vector<content::FileChooserFileInfo> result;
|
||||
file_dialog::Filters filters = GetFileTypesFromAcceptType(
|
||||
params.accept_types);
|
||||
@@ -133,8 +136,7 @@ void WebDialogHelper::RunFileChooser(content::WebContents* web_contents,
|
||||
}
|
||||
}
|
||||
|
||||
web_contents->GetRenderViewHost()->FilesSelectedInChooser(
|
||||
result, params.mode);
|
||||
render_frame_host->FilesSelectedInChooser(result, params.mode);
|
||||
}
|
||||
|
||||
void WebDialogHelper::EnumerateDirectory(content::WebContents* web_contents,
|
||||
|
||||
@@ -13,6 +13,7 @@ class FilePath;
|
||||
|
||||
namespace content {
|
||||
struct FileChooserParams;
|
||||
class RenderFrameHost;
|
||||
class WebContents;
|
||||
}
|
||||
|
||||
@@ -25,7 +26,7 @@ class WebDialogHelper {
|
||||
explicit WebDialogHelper(NativeWindow* window);
|
||||
~WebDialogHelper();
|
||||
|
||||
void RunFileChooser(content::WebContents* web_contents,
|
||||
void RunFileChooser(content::RenderFrameHost* render_frame_host,
|
||||
const content::FileChooserParams& params);
|
||||
void EnumerateDirectory(content::WebContents* web_contents,
|
||||
int request_id,
|
||||
|
||||
@@ -71,7 +71,8 @@ void WindowList::RemoveObserver(WindowListObserver* observer) {
|
||||
void WindowList::CloseAllWindows() {
|
||||
WindowVector windows = GetInstance()->windows_;
|
||||
for (const auto& window : windows)
|
||||
window->Close();
|
||||
if (!window->IsClosed())
|
||||
window->Close();
|
||||
}
|
||||
|
||||
WindowList::WindowList() {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "atom/common/crash_reporter/crash_reporter.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/bind.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "atom/common/node_includes.h"
|
||||
#include "atom/common/native_mate_converters/value_converter.h"
|
||||
#include "base/base64.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/pattern.h"
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/gfx/image/image_skia_operations.h"
|
||||
#include "ui/gfx/image/image_util.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -33,6 +34,8 @@
|
||||
#include "ui/gfx/icon_util.h"
|
||||
#endif
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
@@ -281,6 +284,57 @@ gfx::Size NativeImage::GetSize() {
|
||||
return image_.Size();
|
||||
}
|
||||
|
||||
float NativeImage::GetAspectRatio() {
|
||||
gfx::Size size = GetSize();
|
||||
if (size.IsEmpty())
|
||||
return 1.f;
|
||||
else
|
||||
return static_cast<float>(size.width()) / static_cast<float>(size.height());
|
||||
}
|
||||
|
||||
mate::Handle<NativeImage> NativeImage::Resize(
|
||||
v8::Isolate* isolate, const base::DictionaryValue& options) {
|
||||
gfx::Size size = GetSize();
|
||||
int width = size.width();
|
||||
int height = size.height();
|
||||
bool width_set = options.GetInteger("width", &width);
|
||||
bool height_set = options.GetInteger("height", &height);
|
||||
size.SetSize(width, height);
|
||||
|
||||
if (width_set && !height_set) {
|
||||
// Scale height to preserve original aspect ratio
|
||||
size.set_height(width);
|
||||
size = gfx::ScaleToRoundedSize(size, 1.f, 1.f / GetAspectRatio());
|
||||
} else if (height_set && !width_set) {
|
||||
// Scale width to preserve original aspect ratio
|
||||
size.set_width(height);
|
||||
size = gfx::ScaleToRoundedSize(size, GetAspectRatio(), 1.f);
|
||||
}
|
||||
|
||||
skia::ImageOperations::ResizeMethod method =
|
||||
skia::ImageOperations::ResizeMethod::RESIZE_BEST;
|
||||
std::string quality;
|
||||
options.GetString("quality", &quality);
|
||||
if (quality == "good")
|
||||
method = skia::ImageOperations::ResizeMethod::RESIZE_GOOD;
|
||||
else if (quality == "better")
|
||||
method = skia::ImageOperations::ResizeMethod::RESIZE_BETTER;
|
||||
|
||||
gfx::ImageSkia resized = gfx::ImageSkiaOperations::CreateResizedImage(
|
||||
image_.AsImageSkia(), method, size);
|
||||
return mate::CreateHandle(isolate,
|
||||
new NativeImage(isolate, gfx::Image(resized)));
|
||||
}
|
||||
|
||||
mate::Handle<NativeImage> NativeImage::Crop(v8::Isolate* isolate,
|
||||
const gfx::Rect& rect) {
|
||||
gfx::ImageSkia cropped = gfx::ImageSkiaOperations::ExtractSubset(
|
||||
image_.AsImageSkia(), rect);
|
||||
return mate::CreateHandle(isolate,
|
||||
new NativeImage(isolate, gfx::Image(cropped)));
|
||||
}
|
||||
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
void NativeImage::SetTemplateImage(bool setAsTemplate) {
|
||||
}
|
||||
@@ -381,6 +435,9 @@ void NativeImage::BuildPrototype(
|
||||
.SetMethod("getSize", &NativeImage::GetSize)
|
||||
.SetMethod("setTemplateImage", &NativeImage::SetTemplateImage)
|
||||
.SetMethod("isTemplateImage", &NativeImage::IsTemplateImage)
|
||||
.SetMethod("resize", &NativeImage::Resize)
|
||||
.SetMethod("crop", &NativeImage::Crop)
|
||||
.SetMethod("getAspectRatio", &NativeImage::GetAspectRatio)
|
||||
// TODO(kevinsawicki): Remove in 2.0, deprecate before then with warnings
|
||||
.SetMethod("toPng", &NativeImage::ToPNG)
|
||||
.SetMethod("toJpeg", &NativeImage::ToJPEG);
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "base/values.h"
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
@@ -75,9 +77,14 @@ class NativeImage : public mate::Wrappable<NativeImage> {
|
||||
v8::Local<v8::Value> GetNativeHandle(
|
||||
v8::Isolate* isolate,
|
||||
mate::Arguments* args);
|
||||
mate::Handle<NativeImage> Resize(v8::Isolate* isolate,
|
||||
const base::DictionaryValue& options);
|
||||
mate::Handle<NativeImage> Crop(v8::Isolate* isolate,
|
||||
const gfx::Rect& rect);
|
||||
std::string ToDataURL();
|
||||
bool IsEmpty();
|
||||
gfx::Size GetSize();
|
||||
float GetAspectRatio();
|
||||
|
||||
// Mark the image as template image.
|
||||
void SetTemplateImage(bool setAsTemplate);
|
||||
|
||||
@@ -104,7 +104,7 @@ void Initialize(v8::Local<v8::Object> exports, v8::Local<v8::Value> unused,
|
||||
dict.SetMethod("setRemoteObjectFreer", &atom::RemoteObjectFreer::BindTo);
|
||||
dict.SetMethod("createIDWeakMap", &atom::api::KeyWeakMap<int32_t>::Create);
|
||||
dict.SetMethod("createDoubleIDWeakMap",
|
||||
&atom::api::KeyWeakMap<std::pair<int32_t, int32_t>>::Create);
|
||||
&atom::api::KeyWeakMap<std::pair<int64_t, int32_t>>::Create);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -79,10 +79,6 @@ void FatalErrorCallback(const char* location, const char* message) {
|
||||
Crash();
|
||||
}
|
||||
|
||||
void Log(const base::string16& message) {
|
||||
std::cout << message << std::flush;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -117,8 +113,10 @@ void AtomBindings::BindTo(v8::Isolate* isolate,
|
||||
mate::Dictionary versions;
|
||||
if (dict.Get("versions", &versions)) {
|
||||
versions.Set(ATOM_PROJECT_NAME, ATOM_VERSION_STRING);
|
||||
versions.Set("atom-shell", ATOM_VERSION_STRING); // For compatibility.
|
||||
versions.Set("chrome", CHROME_VERSION_STRING);
|
||||
|
||||
// TODO(kevinsawicki): Remove in 2.0
|
||||
versions.Set("atom-shell", ATOM_VERSION_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,4 +153,9 @@ void AtomBindings::OnCallNextTick(uv_async_t* handle) {
|
||||
self->pending_next_ticks_.clear();
|
||||
}
|
||||
|
||||
// static
|
||||
void AtomBindings::Log(const base::string16& message) {
|
||||
std::cout << message << std::flush;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -24,9 +24,11 @@ class AtomBindings {
|
||||
virtual ~AtomBindings();
|
||||
|
||||
// Add process.atomBinding function, which behaves like process.binding but
|
||||
// load native code from atom-shell instead.
|
||||
// load native code from Electron instead.
|
||||
void BindTo(v8::Isolate* isolate, v8::Local<v8::Object> process);
|
||||
|
||||
static void Log(const base::string16& message);
|
||||
|
||||
private:
|
||||
void ActivateUVLoop(v8::Isolate* isolate);
|
||||
|
||||
|
||||
@@ -12,8 +12,7 @@ namespace atom {
|
||||
|
||||
ObjectLifeMonitor::ObjectLifeMonitor(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> target)
|
||||
: isolate_(isolate),
|
||||
context_(isolate, isolate->GetCurrentContext()),
|
||||
: context_(isolate, isolate->GetCurrentContext()),
|
||||
target_(isolate, target),
|
||||
weak_ptr_factory_(this) {
|
||||
target_.SetWeak(this, OnObjectGC, v8::WeakCallbackType::kParameter);
|
||||
|
||||
@@ -22,7 +22,6 @@ class ObjectLifeMonitor {
|
||||
static void OnObjectGC(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
|
||||
static void Free(const v8::WeakCallbackInfo<ObjectLifeMonitor>& data);
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Context> context_;
|
||||
v8::Global<v8::Object> target_;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#define ATOM_COMMON_ATOM_VERSION_H_
|
||||
|
||||
#define ATOM_MAJOR_VERSION 1
|
||||
#define ATOM_MINOR_VERSION 3
|
||||
#define ATOM_PATCH_VERSION 6
|
||||
#define ATOM_MINOR_VERSION 4
|
||||
#define ATOM_PATCH_VERSION 4
|
||||
|
||||
#define ATOM_VERSION_IS_RELEASE 1
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef ATOM_COMMON_CHROME_VERSION_H_
|
||||
#define ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
#define CHROME_VERSION_STRING "52.0.2743.82"
|
||||
#define CHROME_VERSION_STRING "53.0.2785.113"
|
||||
#define CHROME_VERSION "v" CHROME_VERSION_STRING
|
||||
|
||||
#endif // ATOM_COMMON_CHROME_VERSION_H_
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -45,4 +46,11 @@ SkColor ParseHexColor(const std::string& color_string) {
|
||||
return SkColorSetARGB(bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
}
|
||||
|
||||
std::string ToRGBHex(SkColor color) {
|
||||
return base::StringPrintf("#%02X%02X%02X",
|
||||
SkColorGetR(color),
|
||||
SkColorGetG(color),
|
||||
SkColorGetB(color));
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
@@ -14,6 +14,9 @@ namespace atom {
|
||||
// Parse hex color like "#FFF" or "#EFEFEF"
|
||||
SkColor ParseHexColor(const std::string& name);
|
||||
|
||||
// Convert color to RGB hex value like "#ABCDEF"
|
||||
std::string ToRGBHex(SkColor color);
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_COMMON_COLOR_UTIL_H_
|
||||
|
||||
@@ -25,13 +25,14 @@ CrashReporter::~CrashReporter() {
|
||||
void CrashReporter::Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler,
|
||||
const StringMap& extra_parameters) {
|
||||
SetUploadParameters(extra_parameters);
|
||||
|
||||
InitBreakpad(product_name, ATOM_VERSION_STRING, company_name, submit_url,
|
||||
auto_submit, skip_system_crash_handler);
|
||||
crashes_dir, auto_submit, skip_system_crash_handler);
|
||||
}
|
||||
|
||||
void CrashReporter::SetUploadParameters(const StringMap& parameters) {
|
||||
@@ -43,11 +44,12 @@ void CrashReporter::SetUploadParameters(const StringMap& parameters) {
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporter::GetUploadedReports(const std::string& path) {
|
||||
CrashReporter::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
std::string file_content;
|
||||
std::vector<CrashReporter::UploadReportResult> result;
|
||||
if (base::ReadFileToString(base::FilePath::FromUTF8Unsafe(path),
|
||||
&file_content)) {
|
||||
base::FilePath uploads_path =
|
||||
crashes_dir.Append(FILE_PATH_LITERAL("uploads.log"));
|
||||
if (base::ReadFileToString(uploads_path, &file_content)) {
|
||||
std::vector<std::string> reports = base::SplitString(
|
||||
file_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
for (const std::string& report : reports) {
|
||||
@@ -68,6 +70,7 @@ void CrashReporter::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace crash_reporter {
|
||||
@@ -24,12 +25,13 @@ class CrashReporter {
|
||||
void Start(const std::string& product_name,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler,
|
||||
const StringMap& extra_parameters);
|
||||
|
||||
virtual std::vector<CrashReporter::UploadReportResult> GetUploadedReports(
|
||||
const std::string& path);
|
||||
const base::FilePath& crashes_dir);
|
||||
|
||||
protected:
|
||||
CrashReporter();
|
||||
@@ -39,6 +41,7 @@ class CrashReporter {
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler);
|
||||
virtual void SetUploadParameters();
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/singleton.h"
|
||||
#include "base/process/memory.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "vendor/breakpad/src/client/linux/handler/exception_handler.h"
|
||||
#include "vendor/breakpad/src/common/linux/linux_libc_support.h"
|
||||
|
||||
@@ -60,9 +59,10 @@ void CrashReporterLinux::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {
|
||||
EnableCrashDumping(product_name);
|
||||
EnableCrashDumping(crashes_dir);
|
||||
|
||||
crash_keys_.SetKeyValue("prod", ATOM_PRODUCT_NAME);
|
||||
crash_keys_.SetKeyValue("ver", version.c_str());
|
||||
@@ -77,16 +77,13 @@ void CrashReporterLinux::SetUploadParameters() {
|
||||
upload_parameters_["platform"] = "linux";
|
||||
}
|
||||
|
||||
void CrashReporterLinux::EnableCrashDumping(const std::string& product_name) {
|
||||
std::string dump_dir = "/tmp/" + product_name + " Crashes";
|
||||
base::FilePath dumps_path(dump_dir);
|
||||
base::CreateDirectory(dumps_path);
|
||||
void CrashReporterLinux::EnableCrashDumping(const base::FilePath& crashes_dir) {
|
||||
base::CreateDirectory(crashes_dir);
|
||||
|
||||
std::string log_file = base::StringPrintf(
|
||||
"%s/%s", dump_dir.c_str(), "uploads.log");
|
||||
std::string log_file = crashes_dir.Append("uploads.log").value();
|
||||
strncpy(g_crash_log_path, log_file.c_str(), sizeof(g_crash_log_path));
|
||||
|
||||
MinidumpDescriptor minidump_descriptor(dumps_path.value());
|
||||
MinidumpDescriptor minidump_descriptor(crashes_dir.value());
|
||||
minidump_descriptor.set_size_limit(kMaxMinidumpFileSize);
|
||||
|
||||
breakpad_.reset(new ExceptionHandler(
|
||||
|
||||
@@ -31,6 +31,7 @@ class CrashReporterLinux : public CrashReporter {
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
@@ -41,7 +42,7 @@ class CrashReporterLinux : public CrashReporter {
|
||||
CrashReporterLinux();
|
||||
virtual ~CrashReporterLinux();
|
||||
|
||||
void EnableCrashDumping(const std::string& product_name);
|
||||
void EnableCrashDumping(const base::FilePath& crashes_dir);
|
||||
|
||||
static bool CrashDone(const google_breakpad::MinidumpDescriptor& minidump,
|
||||
void* context,
|
||||
|
||||
@@ -27,6 +27,7 @@ class CrashReporterMac : public CrashReporter {
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
@@ -42,7 +43,7 @@ class CrashReporterMac : public CrashReporter {
|
||||
const base::StringPiece& value);
|
||||
|
||||
std::vector<UploadReportResult> GetUploadedReports(
|
||||
const std::string& path) override;
|
||||
const base::FilePath& crashes_dir) override;
|
||||
|
||||
std::unique_ptr<crashpad::SimpleStringDictionary> simple_string_dictionary_;
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/mac/bundle_locations.h"
|
||||
#include "base/mac/mac_util.h"
|
||||
@@ -31,15 +30,14 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {
|
||||
// check whether crashpad has been initilized.
|
||||
// Only need to initilize once.
|
||||
// check whether crashpad has been initialized.
|
||||
// Only need to initialize once.
|
||||
if (simple_string_dictionary_)
|
||||
return;
|
||||
|
||||
std::string dump_dir = "/tmp/" + product_name + " Crashes";
|
||||
base::FilePath database_path(dump_dir);
|
||||
if (is_browser_) {
|
||||
@autoreleasepool {
|
||||
base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
|
||||
@@ -47,7 +45,7 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
framework_bundle_path.Append("Resources").Append("crashpad_handler");
|
||||
|
||||
crashpad::CrashpadClient crashpad_client;
|
||||
if (crashpad_client.StartHandler(handler_path, database_path,
|
||||
if (crashpad_client.StartHandler(handler_path, crashes_dir,
|
||||
submit_url,
|
||||
StringMap(),
|
||||
std::vector<std::string>(),
|
||||
@@ -76,7 +74,7 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name,
|
||||
}
|
||||
if (is_browser_) {
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database =
|
||||
crashpad::CrashReportDatabase::Initialize(database_path);
|
||||
crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
if (database) {
|
||||
database->GetSettings()->SetUploadsEnabled(auto_submit);
|
||||
}
|
||||
@@ -93,16 +91,15 @@ void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key,
|
||||
}
|
||||
|
||||
std::vector<CrashReporter::UploadReportResult>
|
||||
CrashReporterMac::GetUploadedReports(const std::string& path) {
|
||||
CrashReporterMac::GetUploadedReports(const base::FilePath& crashes_dir) {
|
||||
std::vector<CrashReporter::UploadReportResult> uploaded_reports;
|
||||
|
||||
base::FilePath file_path(path);
|
||||
if (!base::PathExists(file_path)) {
|
||||
if (!base::PathExists(crashes_dir)) {
|
||||
return uploaded_reports;
|
||||
}
|
||||
// Load crashpad database.
|
||||
std::unique_ptr<crashpad::CrashReportDatabase> database =
|
||||
crashpad::CrashReportDatabase::Initialize(file_path);
|
||||
crashpad::CrashReportDatabase::Initialize(crashes_dir);
|
||||
DCHECK(database);
|
||||
|
||||
std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
|
||||
|
||||
@@ -149,16 +149,11 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name,
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) {
|
||||
skip_system_crash_handler_ = skip_system_crash_handler;
|
||||
|
||||
base::FilePath temp_dir;
|
||||
if (!base::GetTempDir(&temp_dir)) {
|
||||
LOG(ERROR) << "Cannot get temp directory";
|
||||
return;
|
||||
}
|
||||
|
||||
base::string16 pipe_name = base::ReplaceStringPlaceholders(
|
||||
kPipeNameFormat, base::UTF8ToUTF16(product_name), NULL);
|
||||
base::string16 wait_name = base::ReplaceStringPlaceholders(
|
||||
@@ -177,7 +172,7 @@ void CrashReporterWin::InitBreakpad(const std::string& product_name,
|
||||
breakpad_.reset();
|
||||
|
||||
breakpad_.reset(new google_breakpad::ExceptionHandler(
|
||||
temp_dir.value(),
|
||||
crashes_dir.DirName().value(),
|
||||
FilterCallback,
|
||||
MinidumpCallback,
|
||||
this,
|
||||
|
||||
@@ -27,6 +27,7 @@ class CrashReporterWin : public CrashReporter {
|
||||
const std::string& version,
|
||||
const std::string& company_name,
|
||||
const std::string& submit_url,
|
||||
const base::FilePath& crashes_dir,
|
||||
bool auto_submit,
|
||||
bool skip_system_crash_handler) override;
|
||||
void SetUploadParameters() override;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace crash_service {
|
||||
namespace {
|
||||
|
||||
const char kApplicationName[] = "application-name";
|
||||
const char kCrashesDirectory[] = "crashes-directory";
|
||||
|
||||
const wchar_t kPipeNameFormat[] = L"\\\\.\\pipe\\$1 Crash Service";
|
||||
const wchar_t kStandardLogFile[] = L"operation_log.txt";
|
||||
@@ -25,17 +26,11 @@ void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*,
|
||||
// noop.
|
||||
}
|
||||
|
||||
bool GetCrashServiceDirectory(const std::wstring& application_name,
|
||||
base::FilePath* dir) {
|
||||
base::FilePath temp_dir;
|
||||
if (!base::GetTempDir(&temp_dir))
|
||||
return false;
|
||||
temp_dir = temp_dir.Append(application_name + L" Crashes");
|
||||
bool CreateCrashServiceDirectory(const base::FilePath& temp_dir) {
|
||||
if (!base::PathExists(temp_dir)) {
|
||||
if (!base::CreateDirectory(temp_dir))
|
||||
return false;
|
||||
}
|
||||
*dir = temp_dir;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,9 +54,16 @@ int Main(const wchar_t* cmd) {
|
||||
std::wstring application_name = cmd_line.GetSwitchValueNative(
|
||||
kApplicationName);
|
||||
|
||||
if (!cmd_line.HasSwitch(kCrashesDirectory)) {
|
||||
LOG(ERROR) << "Crashes directory path must be specified with --"
|
||||
<< kCrashesDirectory;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// We use/create a directory under the user's temp folder, for logging.
|
||||
base::FilePath operating_dir;
|
||||
GetCrashServiceDirectory(application_name, &operating_dir);
|
||||
base::FilePath operating_dir(
|
||||
cmd_line.GetSwitchValueNative(kCrashesDirectory));
|
||||
CreateCrashServiceDirectory(operating_dir);
|
||||
base::FilePath log_file = operating_dir.Append(kStandardLogFile);
|
||||
|
||||
// Logging to stderr (to help with debugging failures on the
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
#ifndef ATOM_COMMON_GOOGLE_API_KEY_H_
|
||||
#define ATOM_COMMON_GOOGLE_API_KEY_H_
|
||||
|
||||
#ifndef GOOGLEAPIS_ENDPOINT
|
||||
#define GOOGLEAPIS_ENDPOINT \
|
||||
"https://www.googleapis.com/geolocation/v1/geolocate?key="
|
||||
#endif
|
||||
|
||||
#ifndef GOOGLEAPIS_API_KEY
|
||||
#define GOOGLEAPIS_API_KEY "AIzaSyAQfxPJiounkhOjODEO5ZieffeBv6yft2Q"
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "atom/common/keyboard_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "third_party/WebKit/public/web/WebInputEvent.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
@@ -174,4 +176,33 @@ ui::KeyboardCode KeyboardCodeFromStr(const std::string& str, bool* shifted) {
|
||||
return KeyboardCodeFromKeyIdentifier(str, shifted);
|
||||
}
|
||||
|
||||
int WebEventModifiersToEventFlags(int modifiers) {
|
||||
int flags = 0;
|
||||
|
||||
if (modifiers & blink::WebInputEvent::ShiftKey)
|
||||
flags |= ui::EF_SHIFT_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::ControlKey)
|
||||
flags |= ui::EF_CONTROL_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::AltKey)
|
||||
flags |= ui::EF_ALT_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::MetaKey)
|
||||
flags |= ui::EF_COMMAND_DOWN;
|
||||
if (modifiers & blink::WebInputEvent::CapsLockOn)
|
||||
flags |= ui::EF_CAPS_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::NumLockOn)
|
||||
flags |= ui::EF_NUM_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::ScrollLockOn)
|
||||
flags |= ui::EF_SCROLL_LOCK_ON;
|
||||
if (modifiers & blink::WebInputEvent::LeftButtonDown)
|
||||
flags |= ui::EF_LEFT_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::MiddleButtonDown)
|
||||
flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::RightButtonDown)
|
||||
flags |= ui::EF_RIGHT_MOUSE_BUTTON;
|
||||
if (modifiers & blink::WebInputEvent::IsAutoRepeat)
|
||||
flags |= ui::EF_IS_REPEAT;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
} // namespace atom
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user